mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-27 18:22:02 +01:00
dont blur images in shared posts
This commit is contained in:
parent
40c5e19158
commit
2d2e2332b4
.changeset
src
5
.changeset/brown-lies-hide.md
Normal file
5
.changeset/brown-lies-hide.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"nostrudel": patch
|
||||
---
|
||||
|
||||
Dont blur images on shared notes
|
@ -1,51 +0,0 @@
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import moment from "moment";
|
||||
import { Card, CardBody, CardHeader, Flex, Heading, Link } from "@chakra-ui/react";
|
||||
import { useIsMobile } from "../hooks/use-is-mobile";
|
||||
import { NoteContents } from "./note/note-contents";
|
||||
import { useUserContacts } from "../hooks/use-user-contacts";
|
||||
import { useCurrentAccount } from "../hooks/use-current-account";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
import { UserAvatarLink } from "./user-avatar-link";
|
||||
import { UserLink } from "./user-link";
|
||||
import { UserDnsIdentityIcon } from "./user-dns-identity";
|
||||
import { Bech32Prefix, normalizeToBech32 } from "../helpers/nip19";
|
||||
import { convertTimestampToDate } from "../helpers/date";
|
||||
import useSubject from "../hooks/use-subject";
|
||||
import appSettings from "../services/app-settings";
|
||||
import EventVerificationIcon from "./event-verification-icon";
|
||||
import { useReadRelayUrls } from "../hooks/use-client-relays";
|
||||
|
||||
const EmbeddedNote = ({ note }: { note: NostrEvent }) => {
|
||||
const account = useCurrentAccount();
|
||||
const { showSignatureVerification } = useSubject(appSettings);
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const contacts = useUserContacts(account.pubkey, readRelays);
|
||||
const following = contacts?.contacts || [];
|
||||
|
||||
return (
|
||||
<Card variant="outline">
|
||||
<CardHeader padding="2">
|
||||
<Flex flex="1" gap="2" alignItems="center" wrap="wrap">
|
||||
<UserAvatarLink pubkey={note.pubkey} size="xs" />
|
||||
|
||||
<Heading size="sm" display="inline">
|
||||
<UserLink pubkey={note.pubkey} />
|
||||
</Heading>
|
||||
<UserDnsIdentityIcon pubkey={note.pubkey} onlyIcon />
|
||||
<Flex grow={1} />
|
||||
{showSignatureVerification && <EventVerificationIcon event={note} />}
|
||||
<Link as={RouterLink} to={`/n/${normalizeToBech32(note.id, Bech32Prefix.Note)}`} whiteSpace="nowrap">
|
||||
{moment(convertTimestampToDate(note.created_at)).fromNow()}
|
||||
</Link>
|
||||
</Flex>
|
||||
</CardHeader>
|
||||
<CardBody p="0">
|
||||
<NoteContents event={note} trusted={following.includes(note.pubkey)} maxHeight={200} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmbeddedNote;
|
43
src/components/note/embeded-note.tsx
Normal file
43
src/components/note/embeded-note.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import moment from "moment";
|
||||
import { Card, CardBody, CardHeader, Flex, Heading, Link } from "@chakra-ui/react";
|
||||
import { NoteContents } from "./note-contents";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { UserAvatarLink } from "../user-avatar-link";
|
||||
import { UserLink } from "../user-link";
|
||||
import { UserDnsIdentityIcon } from "../user-dns-identity";
|
||||
import { Bech32Prefix, normalizeToBech32 } from "../../helpers/nip19";
|
||||
import { convertTimestampToDate } from "../../helpers/date";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import appSettings from "../../services/app-settings";
|
||||
import EventVerificationIcon from "../event-verification-icon";
|
||||
import { TrustProvider } from "./trust";
|
||||
|
||||
export default function EmbeddedNote({ note }: { note: NostrEvent }) {
|
||||
const { showSignatureVerification } = useSubject(appSettings);
|
||||
|
||||
return (
|
||||
<TrustProvider event={note}>
|
||||
<Card variant="outline">
|
||||
<CardHeader padding="2">
|
||||
<Flex flex="1" gap="2" alignItems="center" wrap="wrap">
|
||||
<UserAvatarLink pubkey={note.pubkey} size="xs" />
|
||||
|
||||
<Heading size="sm" display="inline">
|
||||
<UserLink pubkey={note.pubkey} />
|
||||
</Heading>
|
||||
<UserDnsIdentityIcon pubkey={note.pubkey} onlyIcon />
|
||||
<Flex grow={1} />
|
||||
{showSignatureVerification && <EventVerificationIcon event={note} />}
|
||||
<Link as={RouterLink} to={`/n/${normalizeToBech32(note.id, Bech32Prefix.Note)}`} whiteSpace="nowrap">
|
||||
{moment(convertTimestampToDate(note.created_at)).fromNow()}
|
||||
</Link>
|
||||
</Flex>
|
||||
</CardHeader>
|
||||
<CardBody p="0">
|
||||
<NoteContents event={note} maxHeight={200} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</TrustProvider>
|
||||
);
|
||||
}
|
@ -2,12 +2,7 @@ import React, { useMemo } from "react";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import moment from "moment";
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
AlertIcon,
|
||||
AlertTitle,
|
||||
Box,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Card,
|
||||
CardBody,
|
||||
@ -18,57 +13,29 @@ import {
|
||||
Heading,
|
||||
IconButton,
|
||||
Link,
|
||||
Spacer,
|
||||
} from "@chakra-ui/react";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { UserAvatarLink } from "../user-avatar-link";
|
||||
import { Bech32Prefix, normalizeToBech32 } from "../../helpers/nip19";
|
||||
|
||||
import { NoteContents } from "./note-contents";
|
||||
import { NoteMenu } from "./note-menu";
|
||||
import { useUserContacts } from "../../hooks/use-user-contacts";
|
||||
import { NoteRelays } from "./note-relays";
|
||||
import { useIsMobile } from "../../hooks/use-is-mobile";
|
||||
import { UserLink } from "../user-link";
|
||||
import { UserDnsIdentityIcon } from "../user-dns-identity";
|
||||
import { convertTimestampToDate } from "../../helpers/date";
|
||||
import { useCurrentAccount } from "../../hooks/use-current-account";
|
||||
import ReactionButton from "./buttons/reaction-button";
|
||||
import NoteZapButton from "./note-zap-button";
|
||||
import { ExpandProvider, useExpand } from "./expanded";
|
||||
import { ExpandProvider } from "./expanded";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import appSettings from "../../services/app-settings";
|
||||
import EventVerificationIcon from "../event-verification-icon";
|
||||
import { ReplyButton } from "./buttons/reply-button";
|
||||
import { RepostButton } from "./buttons/repost-button";
|
||||
import { QuoteRepostButton } from "./buttons/quote-repost-button";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { ExternalLinkIcon } from "../icons";
|
||||
import SensitiveContentWarning from "../sensitive-content-warning";
|
||||
import useAppSettings from "../../hooks/use-app-settings";
|
||||
|
||||
function NoteContentWithWarning({ event, maxHeight }: { event: NostrEvent; maxHeight?: number }) {
|
||||
const account = useCurrentAccount();
|
||||
const expand = useExpand();
|
||||
const settings = useAppSettings();
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const contacts = useUserContacts(account.pubkey, readRelays);
|
||||
const following = contacts?.contacts || [];
|
||||
|
||||
const contentWarning = event.tags.find((t) => t[0] === "content-warning")?.[1];
|
||||
const showContentWarning = settings.showContentWarning && contentWarning && !expand?.expanded;
|
||||
|
||||
return showContentWarning ? (
|
||||
<SensitiveContentWarning description={contentWarning} />
|
||||
) : (
|
||||
<NoteContents
|
||||
event={event}
|
||||
trusted={event.pubkey === account.pubkey || following.includes(event.pubkey)}
|
||||
maxHeight={maxHeight}
|
||||
/>
|
||||
);
|
||||
}
|
||||
import NoteContentWithWarning from "./note-content-with-warning";
|
||||
import { TrustProvider } from "./trust";
|
||||
|
||||
export type NoteProps = {
|
||||
event: NostrEvent;
|
||||
@ -83,50 +50,52 @@ export const Note = React.memo(({ event, maxHeight, variant = "outline" }: NoteP
|
||||
const externalLink = useMemo(() => event.tags.find((t) => t[0] === "mostr"), [event]);
|
||||
|
||||
return (
|
||||
<ExpandProvider>
|
||||
<Card variant={variant}>
|
||||
<CardHeader padding="2">
|
||||
<Flex flex="1" gap="2" alignItems="center" wrap="wrap">
|
||||
<UserAvatarLink pubkey={event.pubkey} size={isMobile ? "xs" : "sm"} />
|
||||
<TrustProvider event={event}>
|
||||
<ExpandProvider>
|
||||
<Card variant={variant}>
|
||||
<CardHeader padding="2">
|
||||
<Flex flex="1" gap="2" alignItems="center" wrap="wrap">
|
||||
<UserAvatarLink pubkey={event.pubkey} size={isMobile ? "xs" : "sm"} />
|
||||
|
||||
<Heading size="sm" display="inline">
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
</Heading>
|
||||
<UserDnsIdentityIcon pubkey={event.pubkey} onlyIcon />
|
||||
<Flex grow={1} />
|
||||
{showSignatureVerification && <EventVerificationIcon event={event} />}
|
||||
<Link as={RouterLink} to={`/n/${normalizeToBech32(event.id, Bech32Prefix.Note)}`} whiteSpace="nowrap">
|
||||
{moment(convertTimestampToDate(event.created_at)).fromNow()}
|
||||
</Link>
|
||||
</Flex>
|
||||
</CardHeader>
|
||||
<CardBody p="0">
|
||||
<NoteContentWithWarning event={event} maxHeight={maxHeight} />
|
||||
</CardBody>
|
||||
<CardFooter padding="2" display="flex" gap="2">
|
||||
<ButtonGroup size="sm" variant="link">
|
||||
<ReplyButton event={event} />
|
||||
<RepostButton event={event} />
|
||||
<QuoteRepostButton event={event} />
|
||||
<NoteZapButton note={event} size="sm" />
|
||||
{showReactions && <ReactionButton note={event} size="sm" />}
|
||||
</ButtonGroup>
|
||||
<Box flexGrow={1} />
|
||||
{externalLink && (
|
||||
<IconButton
|
||||
as={Link}
|
||||
icon={<ExternalLinkIcon />}
|
||||
aria-label="Open External"
|
||||
href={externalLink[1]}
|
||||
size="sm"
|
||||
variant="link"
|
||||
target="_blank"
|
||||
/>
|
||||
)}
|
||||
<NoteRelays event={event} size="sm" variant="link" />
|
||||
<NoteMenu event={event} size="sm" variant="link" aria-label="More Options" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</ExpandProvider>
|
||||
<Heading size="sm" display="inline">
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
</Heading>
|
||||
<UserDnsIdentityIcon pubkey={event.pubkey} onlyIcon />
|
||||
<Flex grow={1} />
|
||||
{showSignatureVerification && <EventVerificationIcon event={event} />}
|
||||
<Link as={RouterLink} to={`/n/${normalizeToBech32(event.id, Bech32Prefix.Note)}`} whiteSpace="nowrap">
|
||||
{moment(convertTimestampToDate(event.created_at)).fromNow()}
|
||||
</Link>
|
||||
</Flex>
|
||||
</CardHeader>
|
||||
<CardBody p="0">
|
||||
<NoteContentWithWarning event={event} maxHeight={maxHeight} />
|
||||
</CardBody>
|
||||
<CardFooter padding="2" display="flex" gap="2">
|
||||
<ButtonGroup size="sm" variant="link">
|
||||
<ReplyButton event={event} />
|
||||
<RepostButton event={event} />
|
||||
<QuoteRepostButton event={event} />
|
||||
<NoteZapButton note={event} size="sm" />
|
||||
{showReactions && <ReactionButton note={event} size="sm" />}
|
||||
</ButtonGroup>
|
||||
<Box flexGrow={1} />
|
||||
{externalLink && (
|
||||
<IconButton
|
||||
as={Link}
|
||||
icon={<ExternalLinkIcon />}
|
||||
aria-label="Open External"
|
||||
href={externalLink[1]}
|
||||
size="sm"
|
||||
variant="link"
|
||||
target="_blank"
|
||||
/>
|
||||
)}
|
||||
<NoteRelays event={event} size="sm" variant="link" />
|
||||
<NoteMenu event={event} size="sm" variant="link" aria-label="More Options" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</ExpandProvider>
|
||||
</TrustProvider>
|
||||
);
|
||||
});
|
||||
|
20
src/components/note/note-content-with-warning.tsx
Normal file
20
src/components/note/note-content-with-warning.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
|
||||
import { NoteContents } from "./note-contents";
|
||||
import { useExpand } from "./expanded";
|
||||
import SensitiveContentWarning from "../sensitive-content-warning";
|
||||
import useAppSettings from "../../hooks/use-app-settings";
|
||||
|
||||
export default function NoteContentWithWarning({ event, maxHeight }: { event: NostrEvent; maxHeight?: number }) {
|
||||
const expand = useExpand();
|
||||
const settings = useAppSettings();
|
||||
|
||||
const contentWarning = event.tags.find((t) => t[0] === "content-warning")?.[1];
|
||||
const showContentWarning = settings.showContentWarning && contentWarning && !expand?.expanded;
|
||||
|
||||
return showContentWarning ? (
|
||||
<SensitiveContentWarning description={contentWarning} />
|
||||
) : (
|
||||
<NoteContents event={event} maxHeight={maxHeight} />
|
||||
);
|
||||
}
|
@ -21,8 +21,9 @@ import {
|
||||
embedNostrHashtags,
|
||||
} from "../embed-types";
|
||||
import { ImageGalleryProvider } from "../image-gallery";
|
||||
import { useTrusted } from "./trust";
|
||||
|
||||
function buildContents(event: NostrEvent | DraftNostrEvent, trusted: boolean = false) {
|
||||
function buildContents(event: NostrEvent | DraftNostrEvent, trusted = false) {
|
||||
let content: EmbedableContent = [event.content.trim()];
|
||||
|
||||
content = embedLightningInvoice(content);
|
||||
@ -59,12 +60,12 @@ const GradientOverlay = styled.div`
|
||||
|
||||
export type NoteContentsProps = {
|
||||
event: NostrEvent | DraftNostrEvent;
|
||||
trusted?: boolean;
|
||||
maxHeight?: number;
|
||||
};
|
||||
|
||||
export const NoteContents = React.memo(({ event, trusted, maxHeight }: NoteContentsProps) => {
|
||||
const content = buildContents(event, trusted ?? false);
|
||||
export const NoteContents = React.memo(({ event, maxHeight }: NoteContentsProps) => {
|
||||
const trusted = useTrusted();
|
||||
const content = buildContents(event, trusted);
|
||||
const expand = useExpand();
|
||||
const [innerHeight, setInnerHeight] = useState(0);
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
import EmbeddedNote from "../embeded-note";
|
||||
import EmbeddedNote from "./embeded-note";
|
||||
import { NoteLink } from "../note-link";
|
||||
|
||||
const QuoteNote = ({ noteId, relay }: { noteId: string; relay?: string }) => {
|
||||
|
53
src/components/note/repost-note.tsx
Normal file
53
src/components/note/repost-note.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import { Box, Flex, Heading, SkeletonText } from "@chakra-ui/react";
|
||||
import { useAsync } from "react-use";
|
||||
import clientRelaysService from "../../services/client-relays";
|
||||
import singleEventService from "../../services/single-event";
|
||||
import { isETag, NostrEvent } from "../../types/nostr-event";
|
||||
import { ErrorFallback } from "../error-boundary";
|
||||
import { Note } from ".";
|
||||
import { NoteMenu } from "./note-menu";
|
||||
import { UserAvatar } from "../user-avatar";
|
||||
import { UserDnsIdentityIcon } from "../user-dns-identity";
|
||||
import { UserLink } from "../user-link";
|
||||
import { unique } from "../../helpers/array";
|
||||
import { TrustProvider } from "./trust";
|
||||
|
||||
export default function RepostNote({ event, maxHeight }: { event: NostrEvent; maxHeight?: number }) {
|
||||
const {
|
||||
value: repostNote,
|
||||
loading,
|
||||
error,
|
||||
} = useAsync(async () => {
|
||||
const [_, eventId, relay] = event.tags.find(isETag) ?? [];
|
||||
if (eventId) {
|
||||
const readRelays = clientRelaysService.getReadUrls();
|
||||
if (relay) readRelays.push(relay);
|
||||
return singleEventService.requestEvent(eventId, unique(readRelays));
|
||||
}
|
||||
return null;
|
||||
}, [event]);
|
||||
|
||||
return (
|
||||
<TrustProvider event={event}>
|
||||
<Flex gap="2" direction="column">
|
||||
<Flex gap="2" alignItems="center" pl="1">
|
||||
<UserAvatar pubkey={event.pubkey} size="xs" />
|
||||
<Heading size="sm" display="inline">
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
</Heading>
|
||||
<UserDnsIdentityIcon pubkey={event.pubkey} onlyIcon />
|
||||
<span>Shared note</span>
|
||||
<Box flex={1} />
|
||||
<NoteMenu event={event} size="sm" variant="link" aria-label="note options" />
|
||||
</Flex>
|
||||
{loading ? (
|
||||
<SkeletonText />
|
||||
) : repostNote ? (
|
||||
<Note event={repostNote} maxHeight={maxHeight} />
|
||||
) : (
|
||||
<ErrorFallback error={error} />
|
||||
)}
|
||||
</Flex>
|
||||
</TrustProvider>
|
||||
);
|
||||
}
|
28
src/components/note/trust.tsx
Normal file
28
src/components/note/trust.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import React, { PropsWithChildren, useContext } from "react";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useUserContacts } from "../../hooks/use-user-contacts";
|
||||
import { useCurrentAccount } from "../../hooks/use-current-account";
|
||||
|
||||
const TrustContext = React.createContext<boolean>(false);
|
||||
|
||||
export function useTrusted() {
|
||||
return useContext(TrustContext);
|
||||
}
|
||||
|
||||
export function TrustProvider({
|
||||
children,
|
||||
event,
|
||||
trust = false,
|
||||
}: PropsWithChildren & { event?: NostrEvent; trust?: boolean }) {
|
||||
const parentTrust = useContext(TrustContext);
|
||||
|
||||
const account = useCurrentAccount();
|
||||
const readRelays = useReadRelayUrls();
|
||||
const contacts = useUserContacts(account.pubkey, readRelays);
|
||||
const following = contacts?.contacts || [];
|
||||
|
||||
const isEventTrusted = trust || (!!event && (event.pubkey === account.pubkey || following.includes(event.pubkey)));
|
||||
|
||||
return <TrustContext.Provider value={parentTrust || isEventTrusted}>{children}</TrustContext.Provider>;
|
||||
}
|
@ -27,6 +27,7 @@ import { ImageIcon } from "../icons";
|
||||
import { NoteLink } from "../note-link";
|
||||
import { NoteContents } from "../note/note-contents";
|
||||
import { PostResults } from "./post-results";
|
||||
import { TrustProvider } from "../note/trust";
|
||||
|
||||
function emptyDraft(): DraftNostrEvent {
|
||||
return {
|
||||
@ -139,7 +140,9 @@ export const PostModal = ({ isOpen, onClose, initialDraft }: PostModalProps) =>
|
||||
</Text>
|
||||
)}
|
||||
{showPreview ? (
|
||||
<NoteContents event={finalizeNote(draft)} trusted />
|
||||
<TrustProvider trust>
|
||||
<NoteContents event={finalizeNote(draft)} />
|
||||
</TrustProvider>
|
||||
) : (
|
||||
<Textarea
|
||||
autoFocus
|
||||
|
@ -1,50 +0,0 @@
|
||||
import { Box, Flex, Heading, SkeletonText } from "@chakra-ui/react";
|
||||
import { useAsync } from "react-use";
|
||||
import clientRelaysService from "../services/client-relays";
|
||||
import singleEventService from "../services/single-event";
|
||||
import { isETag, NostrEvent } from "../types/nostr-event";
|
||||
import { ErrorFallback } from "./error-boundary";
|
||||
import { Note } from "./note";
|
||||
import { NoteMenu } from "./note/note-menu";
|
||||
import { UserAvatar } from "./user-avatar";
|
||||
import { UserDnsIdentityIcon } from "./user-dns-identity";
|
||||
import { UserLink } from "./user-link";
|
||||
import { unique } from "../helpers/array";
|
||||
|
||||
export default function RepostNote({ event, maxHeight }: { event: NostrEvent; maxHeight?: number }) {
|
||||
const {
|
||||
value: repostNote,
|
||||
loading,
|
||||
error,
|
||||
} = useAsync(async () => {
|
||||
const [_, eventId, relay] = event.tags.find(isETag) ?? [];
|
||||
if (eventId) {
|
||||
const readRelays = clientRelaysService.getReadUrls();
|
||||
if (relay) readRelays.push(relay);
|
||||
return singleEventService.requestEvent(eventId, unique(readRelays));
|
||||
}
|
||||
return null;
|
||||
}, [event]);
|
||||
|
||||
return (
|
||||
<Flex gap="2" direction="column">
|
||||
<Flex gap="2" alignItems="center" pl="1">
|
||||
<UserAvatar pubkey={event.pubkey} size="xs" />
|
||||
<Heading size="sm" display="inline">
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
</Heading>
|
||||
<UserDnsIdentityIcon pubkey={event.pubkey} onlyIcon />
|
||||
<span>Shared note</span>
|
||||
<Box flex={1} />
|
||||
<NoteMenu event={event} size="sm" variant="link" aria-label="note options" />
|
||||
</Flex>
|
||||
{loading ? (
|
||||
<SkeletonText />
|
||||
) : repostNote ? (
|
||||
<Note event={repostNote} maxHeight={maxHeight} />
|
||||
) : (
|
||||
<ErrorFallback error={error} />
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -10,7 +10,7 @@ import { useContext } from "react";
|
||||
import { PostModalContext } from "../../providers/post-modal-provider";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useCurrentAccount } from "../../hooks/use-current-account";
|
||||
import RepostNote from "../../components/repost-note";
|
||||
import RepostNote from "../../components/note/repost-note";
|
||||
|
||||
export default function FollowingTab() {
|
||||
const account = useCurrentAccount();
|
||||
|
@ -20,7 +20,7 @@ import moment from "moment";
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
import { RelayIcon } from "../../components/icons";
|
||||
import { Note } from "../../components/note";
|
||||
import RepostNote from "../../components/repost-note";
|
||||
import RepostNote from "../../components/note/repost-note";
|
||||
import { isReply, isRepost, truncatedId } from "../../helpers/nostr-event";
|
||||
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
|
||||
import { useAdditionalRelayContext } from "../../providers/additional-relay-context";
|
||||
|
Loading…
x
Reference in New Issue
Block a user