import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core" import { useDidUpdate } from "@mantine/hooks" import { Constants } from "app/constants" import { markEntry, selectEntry } from "app/slices/entries" import { useAppDispatch, useAppSelector } from "app/store" import { Entry } from "app/types" import React, { useRef } from "react" import { FeedEntryBody } from "./FeedEntryBody" import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader" import { FeedEntryFooter } from "./FeedEntryFooter" import { FeedEntryHeader } from "./FeedEntryHeader" interface FeedEntryProps { entry: Entry expanded: boolean } const useStyles = createStyles((theme, props: FeedEntryProps) => { let backgroundColor if (theme.colorScheme === "dark") backgroundColor = props.entry.read ? "inherit" : theme.colors.dark[5] else backgroundColor = props.entry.read && !props.expanded ? theme.colors.gray[0] : "inherit" return { paper: { backgroundColor, marginTop: theme.spacing.xs, marginBottom: theme.spacing.xs, [theme.fn.smallerThan(Constants.layout.mobileBreakpoint)]: { marginTop: "6px", marginBottom: "6px", }, }, body: { maxWidth: Constants.layout.entryMaxWidth, }, } }) export function FeedEntry(props: FeedEntryProps) { const { classes } = useStyles(props) const viewMode = useAppSelector(state => state.user.settings?.viewMode) const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed) const dispatch = useAppDispatch() const compactHeader = viewMode === "title" && !props.expanded const headerClicked = (e: React.MouseEvent) => { if (e.button === 1 || e.ctrlKey || e.metaKey) { // middle click dispatch(markEntry({ entry: props.entry, read: true })) } else if (e.button === 0) { // main click // don't trigger the link e.preventDefault() dispatch(selectEntry(props.entry)) } } // scroll to entry when expanded // we use useDidUpdate to avoid scrolling towards all entries during initial load when viewMode is "expanded" const ref = useRef(null) useDidUpdate(() => { setTimeout(() => { if (!ref.current) return if (!props.expanded) return if (Constants.layout.isTopVisible(ref.current) && Constants.layout.isBottomVisible(ref.current)) return document.getElementById(Constants.dom.mainScrollAreaId)?.scrollTo({ // having a small gap between the top of the content and the top of the page is sexier top: ref.current.offsetTop - 3, behavior: scrollSpeed && scrollSpeed > 0 ? "smooth" : "auto", }) }) }, [props.expanded, scrollSpeed]) return (
{compactHeader && } {!compactHeader && } {props.expanded && ( )}
) }