Skip to content

Commit

Permalink
react/ratings: adapt ratings buttons to have new icons, more modern c…
Browse files Browse the repository at this point in the history
…ode and tests
  • Loading branch information
vellip committed Nov 19, 2024
1 parent 9cafe0b commit ea2bf02
Show file tree
Hide file tree
Showing 16 changed files with 641 additions and 175 deletions.
3 changes: 2 additions & 1 deletion adhocracy4/comments/static/comments/Comment.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const ReportModal = require('../../../reports/static/reports/react_reports').ReportModal
const RatingBox = require('../../../ratings/static/ratings/react_ratings').RatingBox
const RatingBox = require('../../../ratings/static/ratings/RatingBox')
const Modal = require('../../../static/Modal')
const CommentEditForm = require('./CommentEditForm')
const CommentForm = require('./CommentForm')
Expand Down Expand Up @@ -86,6 +86,7 @@ class Comment extends React.Component {
userRating={this.props.userRating}
userRatingId={this.props.userRatingId}
isReadOnly={this.props.isReadOnly}
isComment
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,38 +71,55 @@ exports[`Comment Component renders comment with creator and comment text 1`] = `
>
<div
class="rating"
data-testid="rating-box"
>
<button
aria-label="Click to vote up"
aria-pressed="false"
class="rating-button rating-up"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-up"
class="fa fa-thumbs-up"
/>
10
<span
class="rating__label"
>
Likes
</span>
<span
class="aural"
>
Click to like
</span>
</button>
<button
aria-label="Click to vote down"
aria-pressed="false"
class="rating-button rating-down"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-down"
class="fa fa-thumbs-down"
/>
2
<span
class="rating__label"
>
Dislikes
</span>
<span
class="aural"
>
Click to dislike
</span>
</button>
</div>
<div
Expand Down Expand Up @@ -345,38 +362,55 @@ exports[`Comment Component renders comment with creator and comment text 1`] = `
>
<div
class="rating"
data-testid="rating-box"
>
<button
aria-label="Click to vote up"
aria-pressed="false"
class="rating-button rating-up"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-up"
class="fa fa-thumbs-up"
/>
10
<span
class="rating__label"
>
Likes
</span>
<span
class="aural"
>
Click to like
</span>
</button>
<button
aria-label="Click to vote down"
aria-pressed="false"
class="rating-button rating-down"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-down"
class="fa fa-thumbs-down"
/>
2
<span
class="rating__label"
>
Dislikes
</span>
<span
class="aural"
>
Click to dislike
</span>
</button>
</div>
<div
Expand Down Expand Up @@ -681,38 +715,55 @@ exports[`Comment Component renders comment with moderator badge 1`] = `
>
<div
class="rating"
data-testid="rating-box"
>
<button
aria-label="Click to vote up"
aria-pressed="false"
class="rating-button rating-up"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-up"
class="fa fa-thumbs-up"
/>
10
<span
class="rating__label"
>
Likes
</span>
<span
class="aural"
>
Click to like
</span>
</button>
<button
aria-label="Click to vote down"
aria-pressed="false"
class="rating-button rating-down"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-down"
class="fa fa-thumbs-down"
/>
2
<span
class="rating__label"
>
Dislikes
</span>
<span
class="aural"
>
Click to dislike
</span>
</button>
</div>
<div
Expand Down Expand Up @@ -960,38 +1011,55 @@ exports[`Comment Component renders comment with moderator badge 1`] = `
>
<div
class="rating"
data-testid="rating-box"
>
<button
aria-label="Click to vote up"
aria-pressed="false"
class="rating-button rating-up"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-up"
class="fa fa-thumbs-up"
/>
10
<span
class="rating__label"
>
Likes
</span>
<span
class="aural"
>
Click to like
</span>
</button>
<button
aria-label="Click to vote down"
aria-pressed="false"
class="rating-button rating-down"
disabled=""
type="button"
>
<i
aria-hidden="true"
class="fa fa-chevron-down"
class="fa fa-thumbs-down"
/>
2
<span
class="rating__label"
>
Dislikes
</span>
<span
class="aural"
>
Click to dislike
</span>
</button>
</div>
<div
Expand Down
4 changes: 2 additions & 2 deletions adhocracy4/comments_async/static/comments_async/comment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import CommentManageDropdown from './comment_manage_dropdown'
import CommentList from './comment_list'
import { ModeratorFeedback } from './moderator_feedback'
import AiReport from './ai_report'

import { RatingBox } from '../../../ratings/static/ratings/react_ratings'
import RatingBox from '../../../ratings/static/ratings/RatingBox'

const translated = {
reportTitle: django.gettext('You want to report this content? Your message will be sent to the moderation. The moderation will look at the reported content. The content will be deleted if it does not meet our discussion rules (netiquette).'),
Expand Down Expand Up @@ -151,6 +150,7 @@ export default class Comment extends React.Component {
userRating={this.props.userRating}
userRatingId={this.props.userRatingId}
isReadOnly={!this.props.has_rating_permission}
isComment
/>
)
}
Expand Down
77 changes: 77 additions & 0 deletions adhocracy4/ratings/static/ratings/RatingBox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useCallback, useMemo, useState } from 'react'
import django from 'django'

import { createOrModifyRating } from './rating_api'
import RatingButton from './RatingButton'
import config from '../../../static/config'

const translations = {
likes: django.gettext('Likes'),
dislikes: django.gettext('Dislikes')
}

const getRedirectUrl = (id) => config.getLoginUrl() + (id ? encodeURIComponent('?comment=' + id) : '')

const RatingBox = ({
positiveRatings,
negativeRatings,
userHasRating,
userRating,
userRatingId,
isReadOnly,
contentType,
objectId,
authenticatedAs,
isComment,
render
}) => {
const [ratings, setRatings] = useState({ negative: negativeRatings, positive: positiveRatings })
const [userRatingData, setUserRatingData] = useState({ userHasRating, userRating, userRatingId })

const clickHandler = useCallback(async (number) => {
if (!authenticatedAs) {
window.location.href = getRedirectUrl(isComment && objectId)
}
const [ratings, _userRatingData] = await createOrModifyRating(number, objectId, contentType, userRatingData.userRatingId)

setRatings(ratings)
setUserRatingData({ ...userRatingData, ..._userRatingData })
}, [authenticatedAs, objectId, contentType, userRatingData, isComment])

const customChildren = useMemo(() => {
if (render && typeof render === 'function') {
return render({ ratings, userRatingData, isReadOnly, clickHandler })
}
return null
}, [clickHandler, isReadOnly, ratings, render, userRatingData])

// return either custom html from the render prop or the default
return customChildren ?? (
<div className="rating" data-testid="rating-box">
<RatingButton
isReadOnly={isReadOnly}
onClick={clickHandler}
active={userRatingData.userRating === 1}
rating={1}
authenticatedAs={authenticatedAs}
>
<i className="fa fa-thumbs-up" aria-hidden="true" />{' '}
{ratings.positive}{' '}
<span className="rating__label">{translations.likes}</span>
</RatingButton>
<RatingButton
isReadOnly={isReadOnly}
onClick={clickHandler}
active={userRatingData.userRating === -1}
rating={-1}
authenticatedAs={authenticatedAs}
>
<i className="fa fa-thumbs-down" aria-hidden="true" />{' '}
{ratings.negative}{' '}
<span className="rating__label">{translations.dislikes}</span>
</RatingButton>
</div>
)
}

export default RatingBox
44 changes: 44 additions & 0 deletions adhocracy4/ratings/static/ratings/RatingButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react'
import django from 'django'

const translations = {
upvote: django.gettext('Click to like'),
downvote: django.gettext('Click to dislike')
}

const RatingButton = ({
rating,
active,
onClick,
authenticatedAs,
isReadOnly,
children
}) => {
const onClickWrapper = () => {
if (isReadOnly) {
return null
}

onClick(active ? 0 : rating)
}

const type = rating === -1 ? 'down' : 'up'
const cssClasses = active
? 'rating-button rating-' + type + ' is-selected'
: 'rating-button rating-' + type

return (
<button
aria-pressed={active}
className={cssClasses}
disabled={authenticatedAs !== null && isReadOnly}
onClick={onClickWrapper}
type="button"
>
{children}
<span className="aural">{type === 'up' ? translations.upvote : translations.downvote}</span>
</button>
)
}

export default RatingButton
Loading

0 comments on commit ea2bf02

Please sign in to comment.