creator only like reactions

This commit is contained in:
Sean Yesmunt 2020-10-27 12:24:31 -04:00
parent 92f3337c4c
commit ad20e355cf
10 changed files with 100 additions and 14 deletions

View file

@ -26,6 +26,7 @@ YRBL_HAPPY_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-happy/7aa
YRBL_SAD_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-sad/c2d9649633d974e5ffb503925e1f17d951f1bd0f/f262dd YRBL_SAD_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-sad/c2d9649633d974e5ffb503925e1f17d951f1bd0f/f262dd
ENABLE_COMMENT_REACTIONS=false ENABLE_COMMENT_REACTIONS=false
ENABLE_FILE_REACTIONS=false ENABLE_FILE_REACTIONS=false
ENABLE_CREATOR_REACTIONS=false
# OG # OG
OG_TITLE_SUFFIX=| lbry.tv OG_TITLE_SUFFIX=| lbry.tv

View file

@ -31,13 +31,14 @@ const config = {
UNSYNCED_SETTINGS: process.env.UNSYNCED_SETTINGS, UNSYNCED_SETTINGS: process.env.UNSYNCED_SETTINGS,
ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true', ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true',
ENABLE_FILE_REACTIONS: process.env.ENABLE_FILE_REACTIONS === 'true', ENABLE_FILE_REACTIONS: process.env.ENABLE_FILE_REACTIONS === 'true',
ENABLE_CREATOR_REACTIONS: process.env.ENABLE_CREATOR_REACTIONS === 'true',
SIMPLE_SITE: process.env.SIMPLE_SITE === 'true', SIMPLE_SITE: process.env.SIMPLE_SITE === 'true',
SHOW_ADS: process.env.SHOW_ADS === 'true', SHOW_ADS: process.env.SHOW_ADS === 'true',
PINNED_URI_1: process.env.PINNED_URI_1, PINNED_URI_1: process.env.PINNED_URI_1,
PINNED_LABEL_1: process.env.PINNED_LABEL_1, PINNED_LABEL_1: process.env.PINNED_LABEL_1,
PINNED_URI_2: process.env.PINNED_URI_2, PINNED_URI_2: process.env.PINNED_URI_2,
PINNED_LABEL_2: process.env.PINNED_LABEL_2, PINNED_LABEL_2: process.env.PINNED_LABEL_2,
KNOWN_APP_DOMAINS: process.env.KNOWN_APP_DOMAINS KNOWN_APP_DOMAINS: process.env.KNOWN_APP_DOMAINS,
}; };
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`; config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;

View file

@ -315,7 +315,7 @@ function Comment(props: Props) {
icon={ICONS.REPLY} icon={ICONS.REPLY}
/> />
)} )}
{ENABLE_COMMENT_REACTIONS && <CommentReactions commentId={commentId} />} {ENABLE_COMMENT_REACTIONS && <CommentReactions uri={uri} commentId={commentId} />}
</div> </div>
{isReplying && ( {isReplying && (

View file

@ -1,5 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Comment from './view'; import Comment from './view';
import { makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
import { import {
makeSelectMyReactionsForComment, makeSelectMyReactionsForComment,
makeSelectOthersReactionsForComment, makeSelectOthersReactionsForComment,
@ -8,6 +9,8 @@ import {
import { doCommentReact } from 'redux/actions/comments'; import { doCommentReact } from 'redux/actions/comments';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
claimIsMine: makeSelectClaimIsMine(props.uri)(state),
myReacts: makeSelectMyReactionsForComment(props.commentId)(state), myReacts: makeSelectMyReactionsForComment(props.commentId)(state),
othersReacts: makeSelectOthersReactionsForComment(props.commentId)(state), othersReacts: makeSelectOthersReactionsForComment(props.commentId)(state),
activeChannel: selectCommentChannel(state), activeChannel: selectCommentChannel(state),

View file

@ -1,10 +1,11 @@
// @flow // @flow
import { ENABLE_CREATOR_REACTIONS } from 'config';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import * as REACTION_TYPES from 'constants/reactions'; import * as REACTION_TYPES from 'constants/reactions';
import React from 'react'; import React from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import Button from 'component/button'; import Button from 'component/button';
import usePersistedState from 'effects/use-persisted-state'; import ChannelThumbnail from 'component/channelThumbnail';
type Props = { type Props = {
myReacts: Array<string>, myReacts: Array<string>,
@ -12,11 +13,15 @@ type Props = {
react: (string, string) => void, react: (string, string) => void,
commentId: string, commentId: string,
pendingCommentReacts: Array<string>, pendingCommentReacts: Array<string>,
claimIsMine: boolean,
activeChannel: string,
claim: ?ChannelClaim,
}; };
export default function CommentReactions(props: Props) { export default function CommentReactions(props: Props) {
const { myReacts, othersReacts, commentId, react } = props; const { myReacts, othersReacts, commentId, react, claimIsMine, claim, activeChannel } = props;
const [activeChannel] = usePersistedState('comment-channel'); const canCreatorReact = claimIsMine && claim && claim.name === activeChannel;
const authorUri = claim && claim.value_type === 'channel' ? claim.canonical_url : '';
const getCountForReact = type => { const getCountForReact = type => {
let count = 0; let count = 0;
@ -29,6 +34,8 @@ export default function CommentReactions(props: Props) {
return count; return count;
}; };
const creatorLiked = getCountForReact(REACTION_TYPES.CREATOR_LIKE) > 0;
return ( return (
<> <>
<Button <Button
@ -40,7 +47,7 @@ export default function CommentReactions(props: Props) {
})} })}
disabled={!activeChannel} disabled={!activeChannel}
onClick={() => react(commentId, REACTION_TYPES.LIKE)} onClick={() => react(commentId, REACTION_TYPES.LIKE)}
label={getCountForReact(REACTION_TYPES.LIKE)} label={<span className="comment__reaction-count">{getCountForReact(REACTION_TYPES.LIKE)}</span>}
/> />
<Button <Button
requiresAuth={IS_WEB} requiresAuth={IS_WEB}
@ -51,8 +58,26 @@ export default function CommentReactions(props: Props) {
})} })}
disabled={!activeChannel} disabled={!activeChannel}
onClick={() => react(commentId, REACTION_TYPES.DISLIKE)} onClick={() => react(commentId, REACTION_TYPES.DISLIKE)}
label={getCountForReact(REACTION_TYPES.DISLIKE)} label={<span className="comment__reaction-count">{getCountForReact(REACTION_TYPES.DISLIKE)}</span>}
/> />
{ENABLE_CREATOR_REACTIONS && (
<>
{(canCreatorReact || creatorLiked) && (
<Button
iconOnly
disabled={!canCreatorReact || !claimIsMine}
requiresAuth={IS_WEB}
title={claimIsMine ? __('You loved this') : __('Creator loved this')}
icon={creatorLiked ? ICONS.CREATOR_LIKE : ICONS.SUBSCRIBE}
className={classnames('comment__action comment__action--creator-like')}
onClick={() => react(commentId, REACTION_TYPES.CREATOR_LIKE)}
/>
)}
{creatorLiked && <ChannelThumbnail uri={authorUri} className="comment__creator-like" />}
</>
)}
</> </>
); );
} }

View file

@ -195,7 +195,15 @@ function CommentList(props: Props) {
/> />
</span> </span>
)} )}
<Button button="alt" icon={ICONS.REFRESH} title={__('Refresh')} onClick={() => fetchComments(uri)} /> <Button
button="alt"
icon={ICONS.REFRESH}
title={__('Refresh')}
onClick={() => {
fetchComments(uri);
fetchReacts(uri);
}}
/>
</> </>
} }
actions={ actions={

View file

@ -944,4 +944,41 @@ export const icons = {
<polyline points="14.94 12.98 17.37 17.09 14.88 16.99 13.7 19.26 11.19 15.03" /> <polyline points="14.94 12.98 17.37 17.09 14.88 16.99 13.7 19.26 11.19 15.03" />
</svg> </svg>
), ),
[ICONS.CREATOR_LIKE]: (props: CustomProps) => (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={props.size || '18'}
height={props.size || '18'}
fill="none"
stroke="currentColor"
strokeWidth="0"
strokeLinecap="round"
strokeLinejoin="round"
>
<g clipPath="url(#clip0)">
<path
d="M12 4.65882C11.0118 2.4 8.61176 0.564705 6.63529 0.141176C3.24706 -0.564707 0 2.11765 0 6.63529C0 11.2941 12 21.7412 12 21.7412C12 21.7412 24 11.4353 24 6.63529C24 2.11765 20.4706 -0.564707 17.0824 0.282352C15.1059 0.564705 12.7059 2.25882 12 4.65882Z"
fill="url(#paint0_linear)"
/>
</g>
<defs>
<linearGradient
id="paint0_linear"
x1="0.984988"
y1="-1.58654"
x2="28.1615"
y2="20.8252"
gradientUnits="userSpaceOnUse"
>
<stop offset="0.2395" stopColor="#FA3661" />
<stop offset="0.6871" stopColor="#FFB420" />
</linearGradient>
<clipPath id="clip0">
<rect width="24" height="21.7412" fill="white" />
</clipPath>
</defs>
</svg>
),
}; };

View file

@ -126,3 +126,4 @@ export const FIRE = 'Fire';
export const SLIME = 'Slime'; export const SLIME = 'Slime';
export const PIN = 'Pin'; export const PIN = 'Pin';
export const BEST = 'Best'; export const BEST = 'Best';
export const CREATOR_LIKE = 'CreatorLike';

View file

@ -1,2 +1,3 @@
export const LIKE = 'like'; export const LIKE = 'like';
export const DISLIKE = 'dislike'; export const DISLIKE = 'dislike';
export const CREATOR_LIKE = 'creator_like';

View file

@ -254,16 +254,12 @@ $thumbnailWidthSmall: 0rem;
display: flex; display: flex;
margin-top: var(--spacing-s); margin-top: var(--spacing-s);
> *:not(:last-child) { > *:not(:last-of-type) {
margin-right: var(--spacing-m); margin-right: var(--spacing-m);
} }
.icon {
margin-right: var(--spacing-xxs);
}
.button__label { .button__label {
margin-left: 0; margin-left: var(--spacing-xs);
} }
} }
@ -283,6 +279,12 @@ $thumbnailWidthSmall: 0rem;
font-size: var(--font-xsmall); font-size: var(--font-xsmall);
} }
.comment__action--creator-like {
&:disabled {
opacity: 1;
}
}
.comment__action, .comment__action,
.comment__author { .comment__author {
&:focus { &:focus {
@ -314,3 +316,10 @@ $thumbnailWidthSmall: 0rem;
.comment__more-below { .comment__more-below {
margin-top: var(--spacing-l); margin-top: var(--spacing-l);
} }
.comment__creator-like {
height: 1rem;
width: 1rem;
margin-left: 3px;
z-index: 3;
}