Show new comments

This commit is contained in:
ilya-bkv 2023-03-06 17:06:48 +03:00
parent a7b0df4b24
commit b71161ed2d
4 changed files with 31 additions and 29 deletions

View File

@ -1,16 +1,17 @@
.comment { .comment {
margin: 0 -2.4rem 0.5em; margin: 0.5em 0;
padding: 0.8rem 2.4rem; padding: 1rem;
transition: background-color 0.3s; transition: background-color 0.3s;
position: relative; position: relative;
list-style: none; list-style: none;
@include media-breakpoint-down(sm) { &.isNew {
margin-right: -1.2rem; border-radius: 6px;
background: rgba(38, 56, 217, 0.05);
} }
&:last-child { @include media-breakpoint-down(sm) {
margin-bottom: 0; margin-right: -1.2rem;
} }
.comment { .comment {
@ -196,6 +197,7 @@
.commentDetails { .commentDetails {
display: flex; display: flex;
padding: 1rem 0.2rem 0;
margin-bottom: 1.2rem; margin-bottom: 1.2rem;
} }

View File

@ -13,6 +13,8 @@ import { useReactions } from '../../context/reactions'
import { useSnackbar } from '../../context/snackbar' import { useSnackbar } from '../../context/snackbar'
import { ShowIfAuthenticated } from '../_shared/ShowIfAuthenticated' import { ShowIfAuthenticated } from '../_shared/ShowIfAuthenticated'
import { useLocalize } from '../../context/localize' import { useLocalize } from '../../context/localize'
import Cookie from 'js-cookie'
const CommentEditor = lazy(() => import('../_shared/CommentEditor')) const CommentEditor = lazy(() => import('../_shared/CommentEditor'))
type Props = { type Props = {
@ -20,6 +22,7 @@ type Props = {
compact?: boolean compact?: boolean
isArticleAuthor?: boolean isArticleAuthor?: boolean
sortedComments?: Reaction[] sortedComments?: Reaction[]
lastSeen?: Date
} }
export const Comment = (props: Props) => { export const Comment = (props: Props) => {
@ -37,7 +40,7 @@ export const Comment = (props: Props) => {
actions: { showSnackbar } actions: { showSnackbar }
} = useSnackbar() } = useSnackbar()
const canEdit = createMemo(() => props.comment.createdBy?.slug === session()?.user?.slug) const isCommentAuthor = createMemo(() => props.comment.createdBy?.slug === session()?.user?.slug)
const comment = createMemo(() => props.comment) const comment = createMemo(() => props.comment)
const body = createMemo(() => (comment().body || '').trim()) const body = createMemo(() => (comment().body || '').trim())
@ -90,8 +93,9 @@ export const Comment = (props: Props) => {
} }
} }
const createdAt = new Date(comment()?.createdAt)
return ( return (
<li class={styles.comment}> <li class={clsx(styles.comment, { [styles.isNew]: !isCommentAuthor() && createdAt > props.lastSeen })}>
<Show when={!!body()}> <Show when={!!body()}>
<div class={styles.commentContent}> <div class={styles.commentContent}>
<Show <Show
@ -169,7 +173,7 @@ export const Comment = (props: Props) => {
{loading() ? t('Loading') : t('Reply')} {loading() ? t('Loading') : t('Reply')}
</button> </button>
</ShowIfAuthenticated> </ShowIfAuthenticated>
<Show when={canEdit()}> <Show when={isCommentAuthor()}>
<button <button
class={clsx(styles.commentControl, styles.commentControlEdit)} class={clsx(styles.commentControl, styles.commentControlEdit)}
onClick={toggleEditMode} onClick={toggleEditMode}
@ -222,6 +226,7 @@ export const Comment = (props: Props) => {
sortedComments={props.sortedComments} sortedComments={props.sortedComments}
isArticleAuthor={props.isArticleAuthor} isArticleAuthor={props.isArticleAuthor}
comment={c} comment={c}
lastSeen={props.lastSeen}
/> />
)} )}
</For> </For>

View File

@ -47,8 +47,6 @@ export const CommentsTree = (props: Props) => {
} = useReactions() } = useReactions()
const { t } = useLocalize() const { t } = useLocalize()
const [newReactionsCount, setNewReactionsCount] = createSignal<number>(0)
const [newReactions, setNewReactions] = createSignal<Reaction[]>([]) const [newReactions, setNewReactions] = createSignal<Reaction[]>([])
const comments = createMemo(() => const comments = createMemo(() =>
@ -72,31 +70,27 @@ export const CommentsTree = (props: Props) => {
return newSortedComments return newSortedComments
}) })
const updateNewReactionsCount = () => { const dateFromLocalStorage = new Date(localStorage.getItem(`${props.shoutSlug}`))
const dateFromCookie = new Date(Cookie.get(`${props.shoutSlug}`)).valueOf() const currentDate = new Date()
const setCookie = () => Cookie.set(`${props.shoutSlug}`, `${Date.now()}`) const setCookie = () => localStorage.setItem(`${props.shoutSlug}`, `${currentDate}`)
if (!dateFromCookie) {
onMount(() => {
if (!dateFromLocalStorage) {
setCookie() setCookie()
} else if (Date.now() > dateFromCookie) { } else if (currentDate > dateFromLocalStorage) {
const newComments = comments().filter((c) => { const newComments = comments().filter((c) => {
if (c.replyTo) { if (c.replyTo) {
return return
} }
const commentDate = new Date(c.createdAt).valueOf() const created = new Date(c.createdAt)
return commentDate > dateFromCookie return created > dateFromLocalStorage
}) })
setNewReactions(newComments) setNewReactions(newComments)
setNewReactionsCount(newComments.length)
setCookie() setCookie()
} }
}
const { session } = useSession()
onMount(async () => {
updateNewReactionsCount()
}) })
const { session } = useSession()
const [submitted, setSubmitted] = createSignal<boolean>(false) const [submitted, setSubmitted] = createSignal<boolean>(false)
const handleSubmitComment = async (value) => { const handleSubmitComment = async (value) => {
try { try {
@ -116,13 +110,13 @@ export const CommentsTree = (props: Props) => {
<div class={styles.commentsHeaderWrapper}> <div class={styles.commentsHeaderWrapper}>
<h2 id="comments" class={styles.commentsHeader}> <h2 id="comments" class={styles.commentsHeader}>
{t('Comments')} {comments().length.toString() || ''} {t('Comments')} {comments().length.toString() || ''}
<Show when={newReactionsCount() > 0}> <Show when={newReactions().length > 0}>
<span class={styles.newReactions}>&nbsp;+{newReactionsCount()}</span> <span class={styles.newReactions}>&nbsp;+{newReactions().length}</span>
</Show> </Show>
</h2> </h2>
<ul class={clsx(styles.commentsViewSwitcher, 'view-switcher')}> <ul class={clsx(styles.commentsViewSwitcher, 'view-switcher')}>
<Show when={newReactionsCount() > 0}> <Show when={newReactions().length > 0}>
<li classList={{ selected: commentsOrder() === 'newOnly' }}> <li classList={{ selected: commentsOrder() === 'newOnly' }}>
<Button <Button
variant="inline" variant="inline"
@ -160,6 +154,7 @@ export const CommentsTree = (props: Props) => {
sortedComments={sortedComments()} sortedComments={sortedComments()}
isArticleAuthor={Boolean(props.commentAuthors.some((a) => a.slug === session()?.user.slug))} isArticleAuthor={Boolean(props.commentAuthors.some((a) => a.slug === session()?.user.slug))}
comment={reaction} comment={reaction}
lastSeen={dateFromLocalStorage}
/> />
)} )}
</For> </For>

View File

@ -95,7 +95,7 @@ export const AuthorView = (props: AuthorProps) => {
}) })
setCommented(data) setCommented(data)
} catch (error) { } catch (error) {
console.log('!!! error:', error) console.error('[getReactionsBy]:', error)
} }
} }
}) })