diff --git a/.changeset/nasty-carpets-happen.md b/.changeset/nasty-carpets-happen.md new file mode 100644 index 000000000..1388ee1d7 --- /dev/null +++ b/.changeset/nasty-carpets-happen.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +Add max height to timeline notes diff --git a/src/components/hover-link-overlay.tsx b/src/components/hover-link-overlay.tsx index 6d961436e..7e98b0a91 100644 --- a/src/components/hover-link-overlay.tsx +++ b/src/components/hover-link-overlay.tsx @@ -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); } diff --git a/src/components/note/show-more-container.tsx b/src/components/note/show-more-container.tsx new file mode 100644 index 000000000..7078c015c --- /dev/null +++ b/src/components/note/show-more-container.tsx @@ -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) { + const ref = useRef(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 ( + + {children} + + ); +} diff --git a/src/components/note/timeline-note/index.tsx b/src/components/note/timeline-note/index.tsx index bd5d3e833..a5258c512 100644 --- a/src/components/note/timeline-note/index.tsx +++ b/src/components/note/timeline-note/index.tsx @@ -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 & { event: NostrEvent; @@ -101,7 +104,7 @@ export function TimelineNote({ {showReplyLine && } - + diff --git a/src/views/support/components/not-quite-top-zap.tsx b/src/views/support/components/not-quite-top-zap.tsx index d785f96a6..c95fe2ebd 100644 --- a/src/views/support/components/not-quite-top-zap.tsx +++ b/src/views/support/components/not-quite-top-zap.tsx @@ -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 - + diff --git a/src/views/support/components/other-zap.tsx b/src/views/support/components/other-zap.tsx index b4b18dfa2..62773ece4 100644 --- a/src/views/support/components/other-zap.tsx +++ b/src/views/support/components/other-zap.tsx @@ -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 }) { - + diff --git a/src/views/support/components/top-zap.tsx b/src/views/support/components/top-zap.tsx index 6d46401e7..80f4f544b 100644 --- a/src/views/support/components/top-zap.tsx +++ b/src/views/support/components/top-zap.tsx @@ -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 }) { - +