diff --git a/components/comment.js b/components/comment.js index 04e2df65..7097be8b 100644 --- a/components/comment.js +++ b/components/comment.js @@ -120,6 +120,14 @@ export default function Comment ({ } }, [item.id, router.query.commentId]) + useEffect(() => { + if (router.query.commentsViewedAt && + me?.id !== item.user?.id && + new Date(item.createdAt).getTime() > router.query.commentsViewedAt) { + ref.current.classList.add('outline-new-comment') + } + }, [item.id]) + const bottomedOut = depth === COMMENT_DEPTH_LIMIT const op = root.user.name === item.user.name const bountyPaid = root.bountyPaidTo?.includes(Number(item.id)) @@ -127,6 +135,7 @@ export default function Comment ({ return (
ref.current.classList.remove('outline-new-comment')} >
{item.meDontLike diff --git a/components/item-info.js b/components/item-info.js index b175a069..1c23308e 100644 --- a/components/item-info.js +++ b/components/item-info.js @@ -5,7 +5,7 @@ import Badge from 'react-bootstrap/Badge' import Dropdown from 'react-bootstrap/Dropdown' import Countdown from './countdown' import { abbrNum } from '../lib/format' -import { newComments } from '../lib/new-comments' +import { newComments, commentsViewedAt } from '../lib/new-comments' import { timeSince } from '../lib/time' import CowboyHat from './cowboy-hat' import { DeleteDropdownItem } from './delete' @@ -42,7 +42,17 @@ export default function ItemInfo ({ item, pendingSats, full, commentsText, class {abbrNum(item.boost)} boost \ } - + { + const viewedAt = commentsViewedAt(item) + if (viewedAt) { + e.preventDefault() + router.push( + `/items/${item.id}?commentsViewedAt=${viewedAt}`, + `/items/${item.id}`) + } + }} title={`${item.commentSats} sats`} className='text-reset position-relative' + > {item.ncomments} {commentsText || 'comments'} {hasNewComments && diff --git a/components/item.js b/components/item.js index 691b2859..d63444bc 100644 --- a/components/item.js +++ b/components/item.js @@ -12,6 +12,8 @@ import Flag from '../svgs/flag-fill.svg' import ImageIcon from '../svgs/image-fill.svg' import { abbrNum } from '../lib/format' import ItemInfo from './item-info' +import { commentsViewedAt } from '../lib/new-comments' +import { useRouter } from 'next/router' export function SearchTitle ({ title }) { return reactStringReplace(title, /:high\[([^\]]+)\]/g, (match, i) => { @@ -21,6 +23,7 @@ export function SearchTitle ({ title }) { export default function Item ({ item, rank, belowTitle, right, full, children, siblingComments }) { const titleRef = useRef() + const router = useRouter() const [pendingSats, setPendingSats] = useState(0) const image = item.url && item.url.startsWith(process.env.NEXT_PUBLIC_IMGPROXY_URL) @@ -39,7 +42,18 @@ export default function Item ({ item, rank, belowTitle, right, full, children, s : item.meDontLike ? : }
- + { + const viewedAt = commentsViewedAt(item) + if (viewedAt) { + e.preventDefault() + router.push( + `/items/${item.id}?commentsViewedAt=${viewedAt}`, + `/items/${item.id}`) + } + }} ref={titleRef} className={`${styles.title} text-reset me-2`} + > {item.searchTitle ? : item.title} {item.pollCost && } {item.bounty > 0 && diff --git a/lib/new-comments.js b/lib/new-comments.js index 1742879a..20ae8dd4 100644 --- a/lib/new-comments.js +++ b/lib/new-comments.js @@ -14,13 +14,17 @@ export function commentsViewedAfterComment (rootId, createdAt) { window.localStorage.setItem(`${COMMENTS_NUM_PREFIX}:${rootId}`, existingRootComments + 1) } +export function commentsViewedAt (item) { + return window.localStorage.getItem(`${COMMENTS_VIEW_PREFIX}:${item.id}`) +} + export function newComments (item) { if (!item.parentId) { - const commentsViewedAt = window.localStorage.getItem(`${COMMENTS_VIEW_PREFIX}:${item.id}`) - const commentsViewNum = window.localStorage.getItem(`${COMMENTS_NUM_PREFIX}:${item.id}`) + const viewedAt = commentsViewedAt(item) + const viewNum = window.localStorage.getItem(`${COMMENTS_NUM_PREFIX}:${item.id}`) - if (commentsViewedAt && commentsViewNum) { - return commentsViewedAt < new Date(item.lastCommentAt).getTime() || commentsViewNum < item.ncomments + if (viewedAt && viewNum) { + return viewedAt < new Date(item.lastCommentAt).getTime() || viewNum < item.ncomments } } diff --git a/styles/globals.scss b/styles/globals.scss index 2e3221d7..8b50fa52 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -688,6 +688,10 @@ div[contenteditable]:focus, animation: outline 3s linear 1; } +.outline-new-comment { + box-shadow: inset 0 0 1px 1px rgba(0, 123, 190, 0.35); +} + @keyframes spin { 0% { transform: rotate(0deg);