Files
commafeed/commafeed-client/src/components/content/FeedEntry.tsx

122 lines
4.6 KiB
TypeScript
Raw Normal View History

import { Anchor, Box, createStyles, Divider, Paper } from "@mantine/core"
import { MantineNumberSize } from "@mantine/styles"
import { Constants } from "app/constants"
import { markEntry } from "app/slices/entries"
import { useAppDispatch } from "app/store"
2023-04-26 22:39:09 +02:00
import { Entry, ViewMode } from "app/types"
import React from "react"
import { useSwipeable } from "react-swipeable"
import { useViewMode } from "../../hooks/useViewMode"
import { FeedEntryBody } from "./FeedEntryBody"
2022-09-05 13:52:28 +02:00
import { FeedEntryCompactHeader } from "./FeedEntryCompactHeader"
2023-02-24 12:36:22 +01:00
import { FeedEntryContextMenu, useFeedEntryContextMenu } from "./FeedEntryContextMenu"
import { FeedEntryFooter } from "./FeedEntryFooter"
import { FeedEntryHeader } from "./FeedEntryHeader"
interface FeedEntryProps {
entry: Entry
expanded: boolean
showSelectionIndicator: boolean
onHeaderClick: (e: React.MouseEvent) => void
}
2023-04-26 22:39:09 +02:00
const useStyles = createStyles((theme, props: FeedEntryProps & { viewMode?: ViewMode }) => {
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"
2022-11-04 11:11:37 +01:00
let marginY = theme.spacing.xs
2023-04-26 22:39:09 +02:00
if (props.viewMode === "title") marginY = 2
else if (props.viewMode === "cozy") marginY = 6
2022-11-04 11:11:37 +01:00
let mobileMarginY = 6
2023-04-26 22:39:09 +02:00
if (props.viewMode === "title") mobileMarginY = 2
else if (props.viewMode === "cozy") mobileMarginY = 4
2022-11-04 11:11:37 +01:00
2023-04-27 07:57:09 +02:00
let backgroundHoverColor = backgroundColor
if (!props.expanded && !props.entry.read) {
backgroundHoverColor = theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[1]
2023-04-27 07:57:09 +02:00
}
const styles = {
paper: {
backgroundColor,
2022-11-04 11:11:37 +01:00
marginTop: marginY,
marginBottom: marginY,
[theme.fn.smallerThan(Constants.layout.mobileBreakpoint)]: {
2022-11-04 11:11:37 +01:00
marginTop: mobileMarginY,
marginBottom: mobileMarginY,
},
"@media (hover: hover)": {
"&:hover": {
backgroundColor: backgroundHoverColor,
},
2023-04-27 07:57:09 +02:00
},
},
body: {
maxWidth: Constants.layout.entryMaxWidth,
},
}
if (props.showSelectionIndicator) {
2022-10-12 12:23:07 +02:00
styles.paper.borderLeftColor = theme.colorScheme === "dark" ? theme.colors.orange[4] : theme.colors.orange[6]
}
return styles
})
export function FeedEntry(props: FeedEntryProps) {
const { viewMode } = useViewMode()
2023-04-26 22:39:09 +02:00
const { classes } = useStyles({ ...props, viewMode })
2022-11-04 11:11:37 +01:00
const dispatch = useAppDispatch()
const swipeHandlers = useSwipeable({
onSwipedRight: () => dispatch(markEntry({ entry: props.entry, read: !props.entry.read })),
})
2023-02-24 12:36:22 +01:00
const { onContextMenu } = useFeedEntryContextMenu(props.entry)
2023-04-27 07:30:43 +02:00
let paddingX: MantineNumberSize = "xs"
if (viewMode === "title" || viewMode === "cozy") paddingX = 6
let paddingY: MantineNumberSize = "xs"
if (viewMode === "title") paddingY = 4
else if (viewMode === "cozy") paddingY = 8
2023-04-26 22:39:09 +02:00
let borderRadius: MantineNumberSize = "sm"
if (viewMode === "title") borderRadius = 0
else if (viewMode === "cozy") borderRadius = "xs"
2022-11-04 11:11:37 +01:00
2023-04-26 22:39:09 +02:00
const compactHeader = !props.expanded && (viewMode === "title" || viewMode === "cozy")
return (
2022-11-04 11:11:37 +01:00
<Paper withBorder radius={borderRadius} className={classes.paper}>
<Anchor
variant="text"
href={props.entry.url}
target="_blank"
rel="noreferrer"
onClick={props.onHeaderClick}
onAuxClick={props.onHeaderClick}
2023-02-24 12:36:22 +01:00
onContextMenu={onContextMenu}
>
2023-04-27 07:30:43 +02:00
<Box px={paddingX} py={paddingY} {...swipeHandlers}>
{compactHeader && <FeedEntryCompactHeader entry={props.entry} />}
{!compactHeader && <FeedEntryHeader entry={props.entry} expanded={props.expanded} />}
</Box>
</Anchor>
{props.expanded && (
2023-04-27 07:30:43 +02:00
<Box px={paddingX} pb={paddingY}>
<Box className={classes.body} sx={{ direction: props.entry.rtl ? "rtl" : "ltr" }}>
<FeedEntryBody entry={props.entry} />
</Box>
2023-04-27 07:30:43 +02:00
<Divider variant="dashed" my={paddingY} />
<FeedEntryFooter entry={props.entry} />
</Box>
)}
2023-02-24 12:36:22 +01:00
<FeedEntryContextMenu entry={props.entry} />
</Paper>
)
}