Add max height to timeline notes

This commit is contained in:
hzrd149 2025-01-24 12:26:00 -06:00
parent ce1544a856
commit e92d4b3aa5
7 changed files with 87 additions and 13 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Add max height to timeline notes

View File

@ -2,6 +2,9 @@ import { LinkOverlay } from "@chakra-ui/react";
import styled from "@emotion/styled";
const HoverLinkOverlay = styled(LinkOverlay)`
&:before {
z-index: 1;
}
&:hover:before {
background-color: var(--chakra-colors-card-hover-overlay);
}

View File

@ -0,0 +1,63 @@
import styled from "@emotion/styled";
import { useEffect, useRef } from "react";
const StyledOverflowContainer = styled.div`
overflow: hidden;
max-height: 80vh;
position: relative;
&.overflow:after {
content: "Show More";
color: var(--chakra-colors-chakra-body-text);
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 10rem;
background: linear-gradient(180deg, rgb(255 255 255 / 0%) 0%, var(--chakra-colors-chakra-body-bg) 100%);
z-index: 1;
display: flex;
align-items: flex-end;
justify-content: center;
font-size: 1.2rem;
font-weight: bold;
pointer-events: none;
padding-bottom: 1em;
}
`;
export default function ShowMoreContainer({ children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
const ref = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const update = () => {
if (!ref.current) return;
const innerHeight = Array.from(ref.current.children).reduce(
(total, el) => total + el.getBoundingClientRect().height,
0,
);
const height = ref.current.getBoundingClientRect().height;
// add or remove the "overflow" class
if (innerHeight > height && !ref.current.classList.contains("overflow")) ref.current.classList.add("overflow");
else if (ref.current.classList.contains("overflow")) ref.current.classList.remove("overflow");
};
update();
if (ref.current) {
const element = ref.current;
// catch load events that bubble up
element.addEventListener("load", update);
return () => element.removeEventListener("load", update);
}
}, []);
return (
<StyledOverflowContainer ref={ref} {...props}>
{children}
</StyledOverflowContainer>
);
}

View File

@ -1,6 +1,7 @@
import { memo } from "react";
import { memo, useEffect, useRef } from "react";
import {
Box,
BoxProps,
ButtonGroup,
Card,
CardBody,
@ -13,11 +14,12 @@ import {
LinkBox,
useDisclosure,
} from "@chakra-ui/react";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user/user-avatar-link";
import { Link as RouterLink } from "react-router-dom";
import { useObservable } from "applesauce-react/hooks";
import styled from "@emotion/styled";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user/user-avatar-link";
import NoteMenu from "../note-menu";
import UserLink from "../../user/user-link";
import EventZapButton from "../../zap/event-zap-button";
@ -45,6 +47,7 @@ import { getSharableEventAddress } from "../../../services/relay-hints";
import localSettings from "../../../services/local-settings";
import NotePublishedUsing from "../note-published-using";
import useAppSettings from "../../../hooks/use-user-app-settings";
import ShowMoreContainer from "../show-more-container";
export type TimelineNoteProps = Omit<CardProps, "children"> & {
event: NostrEvent;
@ -101,7 +104,7 @@ export function TimelineNote({
<NoteCommunityMetadata event={event} />
{showReplyLine && <ReplyContext event={event} />}
</CardHeader>
<CardBody p="0">
<CardBody as={ShowMoreContainer} p="0">
<NoteContentWithWarning event={event} />
</CardBody>
<CardFooter padding="2" display="flex" gap="2" flexDirection="column" alignItems="flex-start">

View File

@ -1,4 +1,4 @@
import { Box, Card, CardBody, CardHeader, Flex, Grid, Spacer, Text, TextProps } from "@chakra-ui/react";
import { Card, CardBody, CardHeader, Flex, Text, TextProps } from "@chakra-ui/react";
import { getZapPayment, getZapRequest, getZapSender } from "applesauce-core/helpers";
import { NostrEvent } from "nostr-tools";
@ -8,9 +8,9 @@ import TextNoteContents from "../../../components/note/timeline-note/text-note-c
import { LightningIcon } from "../../../components/icons";
import Timestamp from "../../../components/timestamp";
import UserDnsIdentityIcon from "../../../components/user/user-dns-identity-icon";
import DebugEventButton from "../../../components/debug-modal/debug-event-button";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import { TrustProvider } from "../../../providers/local/trust-provider";
import ZapReceiptMenu from "../../../components/zap/zap-receipt-menu";
export function NotQuiteTopZap({ zap, color }: { zap: NostrEvent; color: TextProps["color"] }) {
const sender = getZapSender(zap);
@ -38,7 +38,7 @@ export function NotQuiteTopZap({ zap, color }: { zap: NostrEvent; color: TextPro
<Flex gap="2" ml="auto" alignItems="center">
<Timestamp timestamp={zap.created_at} />
<DebugEventButton event={zap} size="sm" variant="ghost" />
<ZapReceiptMenu zap={zap} size="sm" variant="ghost" aria-label="More options" />
</Flex>
</CardHeader>

View File

@ -1,4 +1,4 @@
import { Box, Card, CardBody, CardHeader, Flex, Spacer, Text, TextProps } from "@chakra-ui/react";
import { Card, CardBody, CardHeader, Flex, Text } from "@chakra-ui/react";
import { getZapPayment, getZapRequest, getZapSender } from "applesauce-core/helpers";
import { NostrEvent } from "nostr-tools";
@ -8,9 +8,9 @@ import TextNoteContents from "../../../components/note/timeline-note/text-note-c
import { LightningIcon } from "../../../components/icons";
import Timestamp from "../../../components/timestamp";
import UserDnsIdentityIcon from "../../../components/user/user-dns-identity-icon";
import DebugEventButton from "../../../components/debug-modal/debug-event-button";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import { TrustProvider } from "../../../providers/local/trust-provider";
import ZapReceiptMenu from "../../../components/zap/zap-receipt-menu";
export function OtherZap({ zap }: { zap: NostrEvent }) {
const sender = getZapSender(zap);
@ -36,7 +36,7 @@ export function OtherZap({ zap }: { zap: NostrEvent }) {
<Flex gap="2" ml="auto" alignItems="center">
<Timestamp timestamp={zap.created_at} />
<DebugEventButton event={zap} size="sm" variant="ghost" />
<ZapReceiptMenu zap={zap} size="sm" variant="ghost" aria-label="More options" />
</Flex>
</CardHeader>

View File

@ -1,4 +1,4 @@
import { Card, CardBody, CardHeader, Flex, Spacer, Text } from "@chakra-ui/react";
import { Card, CardBody, CardHeader, Flex, Text } from "@chakra-ui/react";
import { getZapPayment, getZapRequest, getZapSender } from "applesauce-core/helpers";
import { NostrEvent } from "nostr-tools";
@ -7,9 +7,9 @@ import UserLink from "../../../components/user/user-link";
import TextNoteContents from "../../../components/note/timeline-note/text-note-contents";
import { LightningIcon } from "../../../components/icons";
import Timestamp from "../../../components/timestamp";
import DebugEventButton from "../../../components/debug-modal/debug-event-button";
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import { TrustProvider } from "../../../providers/local/trust-provider";
import ZapReceiptMenu from "../../../components/zap/zap-receipt-menu";
export function TopZap({ zap }: { zap: NostrEvent }) {
const sender = getZapSender(zap);
@ -36,7 +36,7 @@ export function TopZap({ zap }: { zap: NostrEvent }) {
<Flex justifyContent="flex-end" gap="2">
<Timestamp timestamp={zap.created_at} />
<DebugEventButton event={zap} size="xs" variant="ghost" />
<ZapReceiptMenu zap={zap} size="sm" variant="ghost" aria-label="More options" />
</Flex>
</CardHeader>