creator only like reactions
This commit is contained in:
parent
92f3337c4c
commit
ad20e355cf
10 changed files with 100 additions and 14 deletions
|
@ -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
|
||||||
|
|
|
@ -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}`;
|
||||||
|
|
|
@ -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 && (
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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" />}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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={
|
||||||
|
|
|
@ -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>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue