import { Trans } from "@lingui/react/macro" import { Group } from "@mantine/core" import { Item, Menu, Separator } from "react-contexify" import { TbArrowBarToDown, TbExternalLink, TbMail, TbMailOpened, TbRss, TbStar, TbStarOff } from "react-icons/tb" import { Constants } from "@/app/constants" import { markEntriesUpToEntry, markEntry, starEntry } from "@/app/entries/thunks" import { redirectToFeed } from "@/app/redirect/thunks" import { useAppDispatch, useAppSelector } from "@/app/store" import type { Entry } from "@/app/types" import { truncate } from "@/app/utils" import { useBrowserExtension } from "@/hooks/useBrowserExtension" import { useColorScheme } from "@/hooks/useColorScheme" import { tss } from "@/tss" interface FeedEntryContextMenuProps { entry: Entry } const iconSize = 16 const useStyles = tss.create(({ theme, colorScheme }) => ({ menu: { // apply mantine theme from MenuItem.styles.ts fontSize: theme.fontSizes.sm, "--contexify-item-color": `${colorScheme === "dark" ? theme.colors.dark[0] : theme.black} !important`, "--contexify-activeItem-color": `${colorScheme === "dark" ? theme.colors.dark[0] : theme.black} !important`, "--contexify-activeItem-bgColor": `${colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[1]} !important`, }, })) export function FeedEntryContextMenu(props: Readonly) { const colorScheme = useColorScheme() const { classes } = useStyles() const sourceType = useAppSelector(state => state.entries.source.type) const dispatch = useAppDispatch() const { openLinkInBackgroundTab } = useBrowserExtension() return ( { window.open(props.entry.url, "_blank", "noreferrer") dispatch(markEntry({ entry: props.entry, read: true })) }} > Open link in new tab { openLinkInBackgroundTab(props.entry.url) dispatch(markEntry({ entry: props.entry, read: true })) }} > Open link in new background tab {props.entry.markable && ( <> await dispatch(starEntry({ entry: props.entry, starred: !props.entry.starred }))}> {props.entry.starred ? : } {props.entry.starred ? Unstar : Star} await dispatch(markEntry({ entry: props.entry, read: !props.entry.read }))}> {props.entry.read ? : } {props.entry.read ? Keep unread : Mark as read} )} await dispatch(markEntriesUpToEntry(props.entry))}> Mark as read up to here {sourceType === "category" && ( <> { dispatch(redirectToFeed(props.entry.feedId)) }} > Go to {truncate(props.entry.feedName, 30)} )} ) }