cleanup embedded article card

This commit is contained in:
hzrd149
2023-10-17 13:07:49 -05:00
parent 1f73120b2e
commit 0804ee33b4
3 changed files with 73 additions and 25 deletions

View File

@@ -21,7 +21,7 @@ I would recommend you use a browser extension like [Alby](https://getalby.com/)
## Running with docker ## Running with docker
```bash ```bash
docker run --rm -p 8080:80 ghcr.io/hzrd149/nostrudel docker run --rm -p 8080:80 ghcr.io/hzrd149/nostrudel:master
``` ```
## Running locally ## Running locally

View File

@@ -1,5 +1,5 @@
import { useRef } from "react"; import { useRef } from "react";
import { Card, CardProps, Flex, Image, LinkBox, LinkOverlay, Tag, Text } from "@chakra-ui/react"; import { Box, Card, CardBody, CardProps, Flex, Image, LinkBox, LinkOverlay, Tag, Text } from "@chakra-ui/react";
import { import {
getArticleImage, getArticleImage,
@@ -28,29 +28,39 @@ export default function EmbeddedArticle({ article, ...props }: Omit<CardProps, "
useRegisterIntersectionEntity(ref, getEventUID(article)); useRegisterIntersectionEntity(ref, getEventUID(article));
return ( return (
<Card as={LinkBox} ref={ref} p="2" flexDirection="row" {...props}> <Card as={LinkBox} ref={ref} size="sm" {...props}>
<Flex gap="2" direction="column" flex={1}> {image && (
<Flex gap="2" alignItems="center"> <Box
backgroundImage={image}
w="full"
aspectRatio={3 / 1}
hideFrom="md"
backgroundRepeat="no-repeat"
backgroundPosition="center"
backgroundSize="cover"
/>
)}
<CardBody>
{image && (
<Image src={image} alt={title} maxW="3in" maxH="2in" float="right" borderRadius="md" ml="2" hideBelow="md" />
)}
<Flex gap="2" alignItems="center" mb="2">
<UserAvatarLink pubkey={article.pubkey} size="sm" /> <UserAvatarLink pubkey={article.pubkey} size="sm" />
<LinkOverlay href={naddr ? buildAppSelectUrl(naddr, false) : undefined} isExternal fontWeight="bold"> <UserLink pubkey={article.pubkey} fontWeight="bold" isTruncated />
{title} <Timestamp timestamp={getArticlePublishDate(article) ?? article.created_at} />
</LinkOverlay>
<Text>by:</Text>
<UserLink pubkey={article.pubkey} />
<Text>
| <Timestamp timestamp={getArticlePublishDate(article) ?? article.created_at} />
</Text>
</Flex> </Flex>
<Text flex={1}>{summary}</Text> <LinkOverlay href={naddr ? buildAppSelectUrl(naddr, false) : undefined} isExternal fontWeight="bold">
<Flex gap="2" alignItems="center"> {title}
{article.tags </LinkOverlay>
.filter((t) => t[0] === "t") <Text mb="2">{summary}</Text>
.map(([_, hashtag]) => ( {article.tags
<Tag>{hashtag}</Tag> .filter((t) => t[0] === "t")
))} .map(([_, hashtag]) => (
</Flex> <Tag mr="2" mb="2">
</Flex> #{hashtag}
{image && <Image src={image} alt={title} maxW="2in" maxH="2in" float="right" borderRadius="md" />} </Tag>
))}
</CardBody>
</Card> </Card>
); );
} }

View File

@@ -29,6 +29,7 @@ import trustedUserStatsService, { NostrBandUserStats } from "../../services/trus
import VerticalPageLayout from "../../components/vertical-page-layout"; import VerticalPageLayout from "../../components/vertical-page-layout";
import User01 from "../../components/icons/user-01"; import User01 from "../../components/icons/user-01";
import GenericNoteTimeline from "../../components/timeline-page/generic-note-timeline"; import GenericNoteTimeline from "../../components/timeline-page/generic-note-timeline";
import Feather from "../../components/icons/feather";
function ProfileResult({ profile }: { profile: NostrEvent }) { function ProfileResult({ profile }: { profile: NostrEvent }) {
const metadata = parseKind0Event(profile); const metadata = parseKind0Event(profile);
@@ -120,6 +121,25 @@ function NoteSearchResults({ search }: { search: string }) {
); );
} }
function ArticleSearchResults({ search }: { search: string }) {
const searchRelays = useRelaySelectionRelays();
const timeline = useTimelineLoader(
`${search}-article-search`,
searchRelays,
{ search: search || "", kinds: [Kind.Article] },
{ enabled: !!search },
);
const callback = useTimelineCurserIntersectionCallback(timeline);
return (
<IntersectionObserverProvider callback={callback}>
<GenericNoteTimeline timeline={timeline} />
</IntersectionObserverProvider>
);
}
export function SearchPage() { export function SearchPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const qrScannerModal = useDisclosure(); const qrScannerModal = useDisclosure();
@@ -168,7 +188,18 @@ export function SearchPage() {
handleSearchText(searchInput); handleSearchText(searchInput);
}; };
const SearchResults = type === "users" ? ProfileSearchResults : NoteSearchResults; let SearchResults = ProfileSearchResults;
switch (type) {
case "users":
SearchResults = ProfileSearchResults;
break;
case "notes":
SearchResults = NoteSearchResults;
break;
case "articles":
SearchResults = ArticleSearchResults;
break;
}
return ( return (
<VerticalPageLayout> <VerticalPageLayout>
@@ -203,11 +234,18 @@ export function SearchPage() {
> >
Notes Notes
</Button> </Button>
<Button
leftIcon={<Feather />}
colorScheme={type === "articles" ? "primary" : undefined}
onClick={() => mergeSearchParams({ type: "articles" })}
>
Articles
</Button>
</ButtonGroup> </ButtonGroup>
<RelaySelectionButton ml="auto" size="sm" /> <RelaySelectionButton ml="auto" size="sm" />
</Flex> </Flex>
<Flex direction="column" gap="8"> <Flex direction="column" gap="4">
{search ? ( {search ? (
<SearchResults search={search} /> <SearchResults search={search} />
) : ( ) : (