diff --git a/.env.template b/.env.template index 46c0790a6..7d0d60a22 100644 --- a/.env.template +++ b/.env.template @@ -17,3 +17,5 @@ GITHUB_REPO=#{GITHUB_REPO} GATSBY_ALGOLIA_APP_ID=#{GATSBY_ALGOLIA_APP_ID} GATSBY_ALGOLIA_SEARCH_KEY=#{GATSBY_ALGOLIA_SEARCH_KEY} ALGOLIA_ADMIN_KEY=#{ALGOLIA_ADMIN_KEY} +GISCUS_REPO_ID=#{GISCUS_REPO_ID} +GISCUS_CATEGORY_ID=#{GISCUS_CATEGORY_ID} \ No newline at end of file diff --git a/package.json b/package.json index d2208d831..b5771fae6 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@auth0/auth0-react": "^2.2.4", + "@giscus/react": "^3.0.0", "@microsoft/applicationinsights-web": "^3.3.3", "@raae/gatsby-remark-oembed": "^0.3.3", "algoliasearch": "^4.24.0", @@ -116,4 +117,4 @@ "📦 gatsby-plugin-fontawesome-css": "Added to disable Font Awesomes auto CSS insertion and instead insert it at compile time. This stops the brief flicker of the icons stying being incorrect when the page is refreshed" }, "packageManager": "yarn@4.0.1" -} \ No newline at end of file +} diff --git a/src/components/comments/comments.js b/src/components/comments/comments.js index fa5f02d30..dab2e5120 100644 --- a/src/components/comments/comments.js +++ b/src/components/comments/comments.js @@ -8,7 +8,7 @@ const Comments = (props) => { title: props.title, }; return ( -
+
); diff --git a/src/components/discussion/discussion.js b/src/components/discussion/discussion.js new file mode 100644 index 000000000..c6456fbd7 --- /dev/null +++ b/src/components/discussion/discussion.js @@ -0,0 +1,32 @@ +import Giscus from '@giscus/react'; +import React from 'react'; +import PropTypes from 'prop-types'; + +const Discussion = (props) => { + return ( +
+ +
+ ); +}; + +export default Discussion; + +Discussion.propTypes = { + ruleGuid: PropTypes.string.isRequired, +}; diff --git a/src/components/dropdown-icon/dropdown-icon.js b/src/components/dropdown-icon/dropdown-icon.js index 6cb630b63..d734ddccd 100644 --- a/src/components/dropdown-icon/dropdown-icon.js +++ b/src/components/dropdown-icon/dropdown-icon.js @@ -8,7 +8,7 @@ const DropdownIcon = ({ displayActions }) => { const drop = useRef(null); function handleClick(e) { - if (!e.target.closest(`.${drop.current.className}`) && open) { + if (!e.target.closest(`.${drop.current?.className}`) && open) { setOpen(false); } } diff --git a/src/components/reaction/reaction.js b/src/components/reaction/reaction.js deleted file mode 100644 index 7eecc3399..000000000 --- a/src/components/reaction/reaction.js +++ /dev/null @@ -1,211 +0,0 @@ -/* eslint-disable no-console */ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import { useAuth0 } from '@auth0/auth0-react'; -import { - GetReactionForUser, - PostReactionForUser, - ReactionType, - RemoveReaction, -} from '../../services/apiService'; -import { useAuthService } from '../../services/authService'; -import useAppInsights from '../../hooks/useAppInsights'; - -const Reaction = (props) => { - const { ruleId } = props; - const [superLikesCount, setSuperLikesCount] = useState(0); - const [likesCount, setLikesCount] = useState(0); - const [dislikesCount, setDislikesCount] = useState(0); - const [superDislikesCount, setSuperDisikesCount] = useState(0); - const [change, setChange] = useState(0); - const [currentReactionType, setCurrentReactionType] = useState(null); - - const { isAuthenticated, user, loginWithRedirect } = useAuth0(); - const { fetchIdToken } = useAuthService(); - - const { trackException } = useAppInsights(); - - useEffect(() => { - if (isAuthenticated) { - GetReactionForUser(ruleId, user.sub) - .then((success) => { - setSuperLikesCount(success.superLikeCount ?? 0); - setLikesCount(success.likeCount ?? 0); - setDislikesCount(success.dislikeCount ?? 0); - setSuperDisikesCount(success.superDislikeCount ?? 0); - setCurrentReactionType(success.userStatus); - }) - .catch((err) => { - trackException(err, 3); - }); - } else { - setCurrentReactionType(null); - GetReactionForUser(ruleId) - .then((success) => { - setSuperLikesCount(success.superLikeCount ?? 0); - setLikesCount(success.likeCount ?? 0); - setDislikesCount(success.dislikeCount ?? 0); - setSuperDisikesCount(success.superDislikeCount ?? 0); - }) - .catch((err) => { - trackException(err, 3); - }); - } - }, [change, user]); - - function removePreviousReaction() { - if (currentReactionType == ReactionType.SuperLike) { - setSuperLikesCount(superLikesCount - 1); - } else if (currentReactionType == ReactionType.Like) { - setLikesCount(likesCount - 1); - } else if (currentReactionType == ReactionType.DisLike) { - setDislikesCount(dislikesCount - 1); - } else { - setSuperDisikesCount(superDislikesCount - 1); - } - } - - async function onClick(type) { - if (isAuthenticated) { - const data = { - type: type, - ruleGuid: ruleId, - userId: user.sub, - }; - const idToken = await fetchIdToken(); - if (currentReactionType == type) { - removePreviousReaction(); - setCurrentReactionType(null); - RemoveReaction(data, idToken) - .then(() => { - setChange(change + 1); - }) - .catch((err) => { - trackException(err, 3); - }); - } else { - if (type == ReactionType.SuperLike) { - setSuperLikesCount(superLikesCount + 1); - } else if (type == ReactionType.Like) { - setLikesCount(likesCount + 1); - } else if (type == ReactionType.DisLike) { - setDislikesCount(dislikesCount + 1); - } else if (type == ReactionType.SuperDisLike) { - setSuperDisikesCount(superDislikesCount + 1); - } - if (currentReactionType != null && currentReactionType != type) { - removePreviousReaction(); - } - setCurrentReactionType(type); - PostReactionForUser(data, idToken) - .then(() => { - setChange(change + 1); - }) - .catch((err) => { - trackException(err, 3); - }); - } - } else { - if (window.confirm('Sign in to rate this rule')) { - const currentPage = - typeof window !== 'undefined' - ? window.location.pathname.split('/').pop() - : null; - await loginWithRedirect({ - appState: { - targetUrl: currentPage, - }, - }); - } - } - } - - return ( -
-
-
-
-
-
- {superLikesCount} -
-
-
-
-
-
{likesCount}
-
-
-
-
-
- {dislikesCount} -
-
-
-
-
-
- {superDislikesCount} -
-
- ); -}; - -Reaction.propTypes = { - ruleId: PropTypes.string, -}; - -export default Reaction; diff --git a/src/style.css b/src/style.css index 85e63e3e5..9fdb63424 100644 --- a/src/style.css +++ b/src/style.css @@ -1221,66 +1221,6 @@ div.bad-example { @apply text-ssw-red; } -.reaction-grid { - grid-template-columns: auto 2.5rem 2.2rem 0.7rem 2.2rem 2.2rem 0.7rem 2.2rem 2.2rem 0.7rem 2.2rem 2.7rem auto; - display: grid; - grid-template-rows: 2rem; - padding-bottom: 1rem; -} - -.agree-btn-container:after, .agree-btn-container-pressed:after { - content: '\f004'; - font-family: FontAwesome; - font-size: 1.7rem; - padding-left: 0.5rem; -} - -.agree-btn-container-pressed:after, .somewhat-disagree-btn-container-pressed:after, .disagree-btn-container-pressed:after, .somewhat-agree-btn-container-pressed:after { - @apply text-ssw-red; -} - -.agree-btn-container:hover:after, .agree-btn-container-pressed:hover:after, .somewhat-disagree-btn-container:hover:after, .somewhat-disagree-btn-container-pressed:hover:after, .disagree-btn-container:hover:after, .disagree-btn-container-pressed:hover:after, .somewhat-agree-btn-container:hover:after, .somewhat-agree-btn-container-pressed:hover:after { - @apply text-ssw-red; - font-size: 1.8rem; - transition: font-size 0.2s; -} - -.somewhat-agree-btn-container:after, .somewhat-agree-btn-container-pressed:after { - content: '\f164'; - font-family: FontAwesome; - font-size: 1.7rem; -} - -.somewhat-disagree-btn-container:after, .somewhat-disagree-btn-container-pressed:after { - content: '\f165'; - font-family: FontAwesome; - font-size: 1.7rem; - align-self: center; -} - -.disagree-btn-container:after, .disagree-btn-container-pressed:after { - content: '\f05e'; - font-family: FontAwesome; - font-size: 1.7rem; - padding-left: 0.1rem; -} - -.agree-grid-item { - grid-column: 2; -} - -.somewhat-agree-grid-item { - grid-column: 5; -} - -.somewhat-disagree-grid-item { - grid-column: 8; -} - -.disagree-grid-item { - grid-column: 11; -} - .rule-header-container { display: flex; } @@ -1342,7 +1282,7 @@ div.bad-example { margin-top: 0; } -.tooltip, .react-tooltip, .disqus-tooltip, .info-tooltip, .forgot-username-tooltip { +.tooltip, .disqus-tooltip, .info-tooltip, .forgot-username-tooltip { position: relative; margin: 2px 0; height: 2.5rem; @@ -1435,12 +1375,6 @@ div.bad-example { bottom: 105%; } -.react-tooltip .tooltiptext { - margin-left: -53px !important; - bottom: 90%; - width: 80px; -} - .disqus-tooltip .tooltiptext { margin-left: 0 !important; bottom: 2.5rem; @@ -1473,7 +1407,7 @@ div.bad-example { } /* Show the tooltip text when you mouse over the tooltip container */ -.tooltip:hover .tooltiptext, .react-tooltip:hover .tooltiptext, .disqus-tooltip:hover .tooltip, .info-tooltip:hover .tooltiptext, .forgot-username-tooltip:hover .tooltiptext{ +.tooltip:hover .tooltiptext, .disqus-tooltip:hover .tooltip, .info-tooltip:hover .tooltiptext, .forgot-username-tooltip:hover .tooltiptext{ visibility: visible; opacity: 1; padding: 0.3rem !important; @@ -1630,9 +1564,6 @@ div.bad-example { .rule-content { padding: 1rem; } - .reaction-grid { - grid-template-columns: auto 2rem 0.5rem 1.5rem 2.2rem 0.5rem 1.5rem 2.2rem 0.5rem 1.5rem 2.3rem 1rem auto; - } .profile-image { visibility: hidden; grid-column: 1; @@ -2065,7 +1996,7 @@ div.bad-example { border-top: 1px solid #f5f5f5 } -.disqus-box { +.discussion-box { margin-bottom: 5rem; padding: 1rem 1.5rem; } diff --git a/src/templates/rule.js b/src/templates/rule.js index cb6869daf..64b2f1ceb 100644 --- a/src/templates/rule.js +++ b/src/templates/rule.js @@ -18,7 +18,6 @@ import Comments from '../components/comments/comments'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import PropTypes from 'prop-types'; import ReactDOMServer from 'react-dom/server'; -import Reaction from '../components/reaction/reaction'; import RuleSideBar from '../components/rule-side-bar/rule-side-bar'; import formatDistance from 'date-fns/formatDistance'; import { format } from 'date-fns'; @@ -26,6 +25,7 @@ import { useAuth0 } from '@auth0/auth0-react'; import { useAuthService } from '../services/authService'; import { faGithub } from '@fortawesome/free-brands-svg-icons'; import useAppInsights from '../hooks/useAppInsights.js'; +import Discussion from '../components/discussion/discussion.js'; const Rule = ({ data, location }) => { const capitalizeFirstLetter = (string) => { @@ -239,11 +239,7 @@ const Rule = ({ data, location }) => {
-
- -
-
+ >
@@ -256,6 +252,8 @@ const Rule = ({ data, location }) => { />
+ +