From 43891249127424a9d127443429f4ecea5372fe96 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Thu, 9 Mar 2023 15:34:08 +0300 Subject: [PATCH 1/4] Comments rating --- src/components/Article/Comment.module.scss | 33 ------ src/components/Article/Comment.tsx | 15 +-- .../Article/CommentRatingControl.module.scss | 45 +++++++ .../Article/CommentRatingControl.tsx | 112 ++++++++++++++++++ src/utils/jsonParse.ts | 5 + 5 files changed, 165 insertions(+), 45 deletions(-) create mode 100644 src/components/Article/CommentRatingControl.module.scss create mode 100644 src/components/Article/CommentRatingControl.tsx create mode 100644 src/utils/jsonParse.ts diff --git a/src/components/Article/Comment.module.scss b/src/components/Article/Comment.module.scss index 61e01bb9..1ea32cec 100644 --- a/src/components/Article/Comment.module.scss +++ b/src/components/Article/Comment.module.scss @@ -201,39 +201,6 @@ margin-bottom: 1.2rem; } -.commentRating { - align-items: center; - display: flex; - font-weight: bold; -} - -.commentRatingValue { - padding: 0 0.3em; -} - -.commentRatingPositive { - color: #2bb452; -} - -.commentRatingNegative { - color: #d00820; -} - -.commentRatingControl { - border-left: 6px solid transparent; - border-right: 6px solid transparent; - height: 0; - width: 0; -} - -.commentRatingControlUp { - border-bottom: 8px solid rgb(0 0 0 / 40%); -} - -.commentRatingControlDown { - border-top: 8px solid rgb(0 0 0 / 40%); -} - .compactUserpic { height: 28px; width: 28px; diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx index 152b0945..8fe8dce5 100644 --- a/src/components/Article/Comment.tsx +++ b/src/components/Article/Comment.tsx @@ -13,7 +13,7 @@ import { useReactions } from '../../context/reactions' import { useSnackbar } from '../../context/snackbar' import { ShowIfAuthenticated } from '../_shared/ShowIfAuthenticated' import { useLocalize } from '../../context/localize' -import Cookie from 'js-cookie' +import { CommentRatingControl } from './CommentRatingControl' const CommentEditor = lazy(() => import('../_shared/CommentEditor')) @@ -97,6 +97,7 @@ export const Comment = (props: Props) => { return (
  • props.lastSeen })}> +
    {comment().id}
    {
    -
    0, - [styles.commentRatingNegative]: comment().stat.rating < 0 - }} - > -
    +
    diff --git a/src/components/Article/CommentRatingControl.module.scss b/src/components/Article/CommentRatingControl.module.scss new file mode 100644 index 00000000..f1f8cbfa --- /dev/null +++ b/src/components/Article/CommentRatingControl.module.scss @@ -0,0 +1,45 @@ +.commentRating { + align-items: center; + display: flex; + font-weight: bold; + + .commentRatingValue { + padding: 0 0.3em; + margin: 0 0.6rem; + font-size: 1.2rem; + cursor: pointer; + transition: opacity 0.3s ease-in-out; + &:hover { + opacity: 0.5; + } + } + + .commentRatingPositive { + color: #2bb452; + } + + .commentRatingNegative { + color: #d00820; + } + + .commentRatingControl { + border-left: 6px solid transparent; + border-right: 6px solid transparent; + height: 0; + width: 0; + } + + .commentRatingControlUp { + border-bottom: 8px solid rgb(0 0 0 / 40%); + &.voted { + border-bottom-color: #2bb452; + } + } + + .commentRatingControlDown { + border-top: 8px solid rgb(0 0 0 / 40%); + &.voted { + border-top-color: #d00820; + } + } +} diff --git a/src/components/Article/CommentRatingControl.tsx b/src/components/Article/CommentRatingControl.tsx new file mode 100644 index 00000000..9ae4f8d8 --- /dev/null +++ b/src/components/Article/CommentRatingControl.tsx @@ -0,0 +1,112 @@ +import { clsx } from 'clsx' +import styles from './CommentRatingControl.module.scss' +import type { Reaction } from '../../graphql/types.gen' +import { ReactionKind } from '../../graphql/types.gen' +import { useSession } from '../../context/session' +import { useReactions } from '../../context/reactions' +import { createMemo, For } from 'solid-js' +import { loadShout } from '../../stores/zine/articles' +import { Popup } from '../_shared/Popup' + +type Props = { + comment: Reaction +} + +export const CommentRatingControl = (props: Props) => { + const { userSlug } = useSession() + + const { + reactionEntities, + actions: { createReaction, deleteReaction, loadReactionsBy } + } = useReactions() + + const checkReaction = (reactionKind: ReactionKind) => + Object.values(reactionEntities).some( + (r) => + r.kind === reactionKind && + r.createdBy.slug === userSlug() && + r.shout.id === props.comment.shout.id && + r.replyTo === props.comment.id + ) + const isUpvoted = createMemo(() => checkReaction(ReactionKind.Like)) + const isDownvoted = createMemo(() => checkReaction(ReactionKind.Dislike)) + const canVote = userSlug() !== props.comment.createdBy.slug + const shoutRatingReactions = createMemo(() => + Object.values(reactionEntities).filter( + (r) => + [ReactionKind.Like, ReactionKind.Dislike].includes(r.kind) && + r.shout.id === props.comment.shout.id && + r.replyTo === props.comment.id + ) + ) + const deleteCommentReaction = async (reactionKind: ReactionKind) => { + const reactionToDelete = Object.values(reactionEntities).find( + (r) => + r.kind === reactionKind && + r.createdBy.slug === userSlug() && + r.shout.id === props.comment.shout.id && + r.replyTo === props.comment.id + ) + return deleteReaction(reactionToDelete.id) + } + + const handleRatingChange = async (isUpvote: boolean) => { + if (isUpvoted()) { + await deleteCommentReaction(ReactionKind.Like) + } else if (isDownvoted()) { + await deleteCommentReaction(ReactionKind.Dislike) + } else { + console.log('!!! createReaction:') + await createReaction({ + kind: isUpvote ? ReactionKind.Like : ReactionKind.Dislike, + shout: props.comment.shout.id, + replyTo: props.comment.id + }) + } + + await loadShout(props.comment.shout.slug) + await loadReactionsBy({ + by: { shout: props.comment.shout.slug } + }) + } + + return ( +
    +
    + } + variant="tiny" + > +
      + + {(reaction) => ( +
    • + {reaction.kind === ReactionKind.Like ? <>+1 : <>−1} {reaction.createdBy.name} +
    • + )} +
      +
    + +
    + ) +} diff --git a/src/utils/jsonParse.ts b/src/utils/jsonParse.ts new file mode 100644 index 00000000..ae582d55 --- /dev/null +++ b/src/utils/jsonParse.ts @@ -0,0 +1,5 @@ +export const jsonParse = (obj: T) => JSON.parse(JSON.stringify(obj)) + +export const jsonParseLog = (msg: string, obj: T) => { + console.log(`${msg}: `, JSON.parse(JSON.stringify(obj))) +} From 06e68fca4af22831fc0815eab74ef11335cf1ef6 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Thu, 9 Mar 2023 19:19:28 +0300 Subject: [PATCH 2/4] [146] resolve conversation --- src/components/Article/Comment.tsx | 1 - src/components/Article/CommentRatingControl.tsx | 13 +++++++++---- src/utils/clone.ts | 3 +++ src/utils/jsonParse.ts | 5 ----- 4 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 src/utils/clone.ts delete mode 100644 src/utils/jsonParse.ts diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx index 8fe8dce5..21942340 100644 --- a/src/components/Article/Comment.tsx +++ b/src/components/Article/Comment.tsx @@ -97,7 +97,6 @@ export const Comment = (props: Props) => { return (
  • props.lastSeen })}> -
    {comment().id}
    { ) const isUpvoted = createMemo(() => checkReaction(ReactionKind.Like)) const isDownvoted = createMemo(() => checkReaction(ReactionKind.Dislike)) - const canVote = userSlug() !== props.comment.createdBy.slug + const canVote = createMemo(() => userSlug() !== props.comment.createdBy.slug) + const shoutRatingReactions = createMemo(() => Object.values(reactionEntities).filter( (r) => @@ -56,7 +57,6 @@ export const CommentRatingControl = (props: Props) => { } else if (isDownvoted()) { await deleteCommentReaction(ReactionKind.Dislike) } else { - console.log('!!! createReaction:') await createReaction({ kind: isUpvote ? ReactionKind.Like : ReactionKind.Dislike, shout: props.comment.shout.id, @@ -72,8 +72,11 @@ export const CommentRatingControl = (props: Props) => { return (
    + {!canVote()}