feat: replaced respect with reaction and added some options!

This commit is contained in:
Wyatt Johnson
2018-09-26 16:06:35 -06:00
parent 16cbbe8d2c
commit 5acd19790a
16 changed files with 199 additions and 62 deletions
@@ -10,6 +10,7 @@ import * as styles from "./PermalinkView.css";
export interface PermalinkViewProps {
me: PropTypesOf<typeof CommentContainer>["me"];
asset: PropTypesOf<typeof CommentContainer>["asset"];
settings: PropTypesOf<typeof CommentContainer>["settings"];
comment: PropTypesOf<typeof CommentContainer>["comment"] | null;
showAllCommentsHref: string | null;
onShowAllComments: (e: MouseEvent<any>) => void;
@@ -18,6 +19,7 @@ export interface PermalinkViewProps {
const PermalinkView: StatelessComponent<PermalinkViewProps> = ({
showAllCommentsHref,
comment,
settings,
asset,
onShowAllComments,
me,
@@ -46,7 +48,14 @@ const PermalinkView: StatelessComponent<PermalinkViewProps> = ({
<Typography>Comment not found</Typography>
</Localized>
)}
{comment && <CommentContainer me={me} comment={comment} asset={asset} />}
{comment && (
<CommentContainer
settings={settings}
me={me}
comment={comment}
asset={asset}
/>
)}
</div>
);
};
@@ -0,0 +1,43 @@
import React from "react";
import { Button, ButtonIcon, MatchMedia } from "talk-ui/components";
interface ReactionButtonProps {
onButtonClick: () => {};
totalReactions: number;
reacted: boolean | null;
label: string;
labelActive: string | null;
icon: string;
iconActive: string | null;
// color: string;
}
class ReactionButton extends React.Component<ReactionButtonProps> {
public render() {
const { totalReactions, reacted } = this.props;
return (
<Button variant="ghost" size="small" onClick={this.props.onButtonClick}>
<MatchMedia gtWidth="xs">
{!!totalReactions && <span>{totalReactions}</span>}
<ButtonIcon>
{reacted
? this.props.iconActive
? this.props.iconActive
: this.props.icon
: this.props.icon}
</ButtonIcon>
</MatchMedia>
<span>
{reacted
? this.props.labelActive
? this.props.labelActive
: this.props.label
: this.props.label}
</span>
</Button>
);
}
}
export default ReactionButton;
@@ -17,6 +17,7 @@ export interface ReplyListProps {
comments: ReadonlyArray<
{ id: string } & PropTypesOf<typeof CommentContainer>["comment"]
>;
settings: PropTypesOf<typeof CommentContainer>["settings"];
onShowAll?: () => void;
hasMore?: boolean;
disableShowAll?: boolean;
@@ -49,6 +50,7 @@ const ReplyList: StatelessComponent<ReplyListProps> = props => {
me={props.me}
comment={comment}
asset={props.asset}
settings={props.settings}
indentLevel={props.indentLevel}
localReply={props.localReply}
disableReplies={props.disableReplies}
@@ -1,39 +0,0 @@
import { Localized } from "fluent-react/compat";
import React from "react";
import { Button, ButtonIcon, MatchMedia } from "talk-ui/components";
interface RespectButtonProps {
onButtonClick: () => {};
totalReactions: number;
reacted: boolean | null;
}
class RespectButton extends React.Component<RespectButtonProps> {
public render() {
const { totalReactions, reacted } = this.props;
return reacted ? (
<Button variant="ghost" size="small" onClick={this.props.onButtonClick}>
<MatchMedia gtWidth="xs">
{!!totalReactions && <span>{totalReactions}</span>}
<ButtonIcon>thumb_up_alt</ButtonIcon>
</MatchMedia>
<Localized id="comments-respectButton-respected">
<span>Respected</span>
</Localized>
</Button>
) : (
<Button variant="ghost" size="small" onClick={this.props.onButtonClick}>
<MatchMedia gtWidth="xs">
{!!totalReactions && <span>{totalReactions}</span>}
<ButtonIcon>thumb_up_alt</ButtonIcon>
</MatchMedia>
<Localized id="comments-respectButton-respect">
<span>Respect</span>
</Localized>
</Button>
);
}
}
export default RespectButton;
@@ -18,6 +18,8 @@ export interface StreamProps {
isClosed?: boolean;
} & PropTypesOf<typeof CommentContainer>["asset"] &
PropTypesOf<typeof ReplyListContainer>["asset"];
settings: PropTypesOf<typeof CommentContainer>["settings"] &
PropTypesOf<typeof ReplyListContainer>["settings"];
comments: ReadonlyArray<
{ id: string } & PropTypesOf<typeof CommentContainer>["comment"] &
PropTypesOf<typeof ReplyListContainer>["comment"]
@@ -52,10 +54,12 @@ const Stream: StatelessComponent<StreamProps> = props => {
<HorizontalGutter key={comment.id}>
<CommentContainer
me={props.me}
settings={props.settings}
comment={comment}
asset={props.asset}
/>
<ReplyListContainer
settings={props.settings}
me={props.me}
comment={comment}
asset={props.asset}
@@ -8,23 +8,25 @@ import { PropTypesOf } from "talk-framework/types";
import { CommentContainer_asset as AssetData } from "talk-stream/__generated__/CommentContainer_asset.graphql";
import { CommentContainer_comment as CommentData } from "talk-stream/__generated__/CommentContainer_comment.graphql";
import { CommentContainer_me as MeData } from "talk-stream/__generated__/CommentContainer_me.graphql";
import { CommentContainer_settings as SettingsData } from "talk-stream/__generated__/CommentContainer_settings.graphql";
import {
ShowAuthPopupMutation,
withShowAuthPopupMutation,
} from "talk-stream/mutations";
import ReactionButtonContainer from "talk-stream/tabs/comments/containers/ReactionButtonContainer";
import { Button } from "talk-ui/components";
import Comment from "../components/Comment";
import ReplyButton from "../components/Comment/ReplyButton";
import EditCommentFormContainer from "./EditCommentFormContainer";
import PermalinkButtonContainer from "./PermalinkButtonContainer";
import ReplyCommentFormContainer from "./ReplyCommentFormContainer";
import RespectButtonContainer from "./RespectButtonContainer";
interface InnerProps {
me: MeData | null;
comment: CommentData;
asset: AssetData;
settings: SettingsData;
indentLevel?: number;
showAuthPopup: ShowAuthPopupMutation;
/**
@@ -117,6 +119,7 @@ export class CommentContainer extends Component<InnerProps, State> {
public render() {
const {
comment,
settings,
asset,
indentLevel,
localReply,
@@ -166,7 +169,12 @@ export class CommentContainer extends Component<InnerProps, State> {
/>
)}
<PermalinkButtonContainer commentID={comment.id} />
{this.props.me && <RespectButtonContainer comment={comment} />}
{this.props.me && (
<ReactionButtonContainer
comment={comment}
settings={settings}
/>
)}
</>
}
/>
@@ -211,7 +219,12 @@ const enhanced = withShowAuthPopupMutation(
pending
...ReplyCommentFormContainer_comment
...EditCommentFormContainer_comment
...RespectButtonContainer_comment
...ReactionButtonContainer_comment
}
`,
settings: graphql`
fragment CommentContainer_settings on Settings {
...ReactionButtonContainer_settings
}
`,
})(CommentContainer)
@@ -6,6 +6,7 @@ import { PropTypesOf } from "talk-framework/types";
import { LocalReplyListContainer_asset as AssetData } from "talk-stream/__generated__/LocalReplyListContainer_asset.graphql";
import { LocalReplyListContainer_comment as CommentData } from "talk-stream/__generated__/LocalReplyListContainer_comment.graphql";
import { LocalReplyListContainer_me as MeData } from "talk-stream/__generated__/LocalReplyListContainer_me.graphql";
import { LocalReplyListContainer_settings as SettingsData } from "talk-stream/__generated__/LocalReplyListContainer_settings.graphql";
import ReplyList from "../components/ReplyList";
@@ -14,6 +15,7 @@ interface InnerProps {
me: MeData;
asset: AssetData;
comment: CommentData;
settings: SettingsData;
}
/**
@@ -30,6 +32,7 @@ export class LocalReplyListContainer extends Component<InnerProps> {
return (
<ReplyList
me={this.props.me}
settings={this.props.settings}
comment={this.props.comment}
comments={this.props.comment.localReplies}
asset={this.props.asset}
@@ -60,6 +63,11 @@ const enhanced = withFragmentContainer<InnerProps>({
}
}
`,
settings: graphql`
fragment LocalReplyListContainer_settings on Settings {
...CommentContainer_settings
}
`,
})(LocalReplyListContainer);
export type LocalReplyListContainerProps = PropTypesOf<typeof enhanced>;
@@ -8,6 +8,7 @@ import { buildURL, parseURL } from "talk-framework/utils";
import { PermalinkViewContainer_asset as AssetData } from "talk-stream/__generated__/PermalinkViewContainer_asset.graphql";
import { PermalinkViewContainer_comment as CommentData } from "talk-stream/__generated__/PermalinkViewContainer_comment.graphql";
import { PermalinkViewContainer_me as MeData } from "talk-stream/__generated__/PermalinkViewContainer_me.graphql";
import { PermalinkViewContainer_settings as SettingsData } from "talk-stream/__generated__/PermalinkViewContainer_settings.graphql";
import {
SetCommentIDMutation,
withSetCommentIDMutation,
@@ -18,6 +19,7 @@ import PermalinkView from "../components/PermalinkView";
interface PermalinkViewContainerProps {
comment: CommentData | null;
asset: AssetData;
settings: SettingsData;
me: MeData | null;
setCommentID: SetCommentIDMutation;
pym: PymChild | undefined;
@@ -53,12 +55,13 @@ class PermalinkViewContainer extends React.Component<
}
public render() {
const { comment, asset, me } = this.props;
const { comment, asset, me, settings } = this.props;
return (
<PermalinkView
me={me}
asset={asset}
comment={comment}
settings={settings}
showAllCommentsHref={this.getShowAllCommentsHref()}
onShowAllComments={this.showAllComments}
/>
@@ -87,6 +90,11 @@ const enhanced = withContext(ctx => ({
...CommentContainer_me
}
`,
settings: graphql`
fragment PermalinkViewContainer_settings on Settings {
...CommentContainer_settings
}
`,
})(PermalinkViewContainer)
)
);
@@ -1,24 +1,26 @@
import React from "react";
import { graphql } from "react-relay";
import { withFragmentContainer } from "talk-framework/lib/relay";
import { RespectButtonContainer_comment as CommentData } from "talk-stream/__generated__/RespectButtonContainer_comment.graphql";
import { ReactionButtonContainer_comment as CommentData } from "talk-stream/__generated__/ReactionButtonContainer_comment.graphql";
import { ReactionButtonContainer_settings as SettingsData } from "talk-stream/__generated__/ReactionButtonContainer_settings.graphql";
import {
CreateCommentReactionMutation,
DeleteCommentReactionMutation,
withCreateCommentReactionMutation,
withDeleteCommentReactionMutation,
} from "../../../mutations";
import RespectButton from "../components/RespectButton";
} from "talk-stream/mutations";
import ReactionButton from "talk-stream/tabs/comments/components/ReactionButton";
interface RespectButtonContainerProps {
interface ReactionButtonContainerProps {
createCommentReaction: CreateCommentReactionMutation;
deleteCommentReaction: DeleteCommentReactionMutation;
comment: CommentData;
settings: SettingsData;
}
class RespectButtonContainer extends React.Component<
RespectButtonContainerProps
class ReactionButtonContainer extends React.Component<
ReactionButtonContainerProps
> {
private onButtonClick = () => {
const input = {
@@ -40,16 +42,23 @@ class RespectButtonContainer extends React.Component<
reaction: { total: totalReactions },
},
} = this.props.comment;
const {
reaction: { label, labelActive, icon, iconActive },
} = this.props.settings;
const reacted =
this.props.comment.myActionPresence &&
this.props.comment.myActionPresence.reaction;
return (
<RespectButton
<ReactionButton
onButtonClick={this.onButtonClick}
totalReactions={totalReactions}
reacted={reacted}
label={label}
labelActive={labelActive}
icon={icon}
iconActive={iconActive}
/>
);
}
@@ -57,9 +66,9 @@ class RespectButtonContainer extends React.Component<
export default withDeleteCommentReactionMutation(
withCreateCommentReactionMutation(
withFragmentContainer<RespectButtonContainerProps>({
withFragmentContainer<ReactionButtonContainerProps>({
comment: graphql`
fragment RespectButtonContainer_comment on Comment {
fragment ReactionButtonContainer_comment on Comment {
id
myActionPresence {
reaction
@@ -71,6 +80,16 @@ export default withDeleteCommentReactionMutation(
}
}
`,
})(RespectButtonContainer)
settings: graphql`
fragment ReactionButtonContainer_settings on Settings {
reaction {
label
labelActive
icon
iconActive
}
}
`,
})(ReactionButtonContainer)
)
);
@@ -7,6 +7,7 @@ import { PropTypesOf } from "talk-framework/types";
import { ReplyListContainer1_asset as AssetData } from "talk-stream/__generated__/ReplyListContainer1_asset.graphql";
import { ReplyListContainer1_comment as CommentData } from "talk-stream/__generated__/ReplyListContainer1_comment.graphql";
import { ReplyListContainer1_me as MeData } from "talk-stream/__generated__/ReplyListContainer1_me.graphql";
import { ReplyListContainer1_settings as SettingsData } from "talk-stream/__generated__/ReplyListContainer1_settings.graphql";
import {
COMMENT_SORT,
ReplyListContainer1PaginationQueryVariables,
@@ -20,6 +21,7 @@ export interface InnerProps {
me: MeData | null;
asset: AssetData;
comment: CommentData;
settings: SettingsData;
relay: RelayPaginationProp;
indentLevel: number;
ReplyListComponent: React.ComponentType<any> | undefined;
@@ -51,6 +53,7 @@ export class ReplyListContainer extends React.Component<InnerProps> {
comment={this.props.comment}
comments={comments}
asset={this.props.asset}
settings={this.props.settings}
onShowAll={this.showAll}
hasMore={this.props.relay.hasMore()}
disableShowAll={this.state.disableShowAll}
@@ -86,6 +89,7 @@ function createReplyListContainer(
me: GraphQLTaggedNode;
asset: GraphQLTaggedNode;
comment: GraphQLTaggedNode;
settings: GraphQLTaggedNode;
},
query: GraphQLTaggedNode,
ReplyListComponent?: React.ComponentType<any>,
@@ -137,6 +141,12 @@ const ReplyListContainer5 = createReplyListContainer(
...LocalReplyListContainer_me
}
`,
settings: graphql`
fragment ReplyListContainer5_settings on Settings {
...LocalReplyListContainer_settings
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer5_asset on Asset {
...CommentContainer_asset
@@ -192,6 +202,12 @@ const ReplyListContainer4 = createReplyListContainer(
...CommentContainer_me
}
`,
settings: graphql`
fragment ReplyListContainer4_settings on Settings {
...ReplyListContainer5_settings
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer4_asset on Asset {
...ReplyListContainer5_asset
@@ -246,6 +262,12 @@ const ReplyListContainer3 = createReplyListContainer(
...CommentContainer_me
}
`,
settings: graphql`
fragment ReplyListContainer3_settings on Settings {
...ReplyListContainer4_settings
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer3_asset on Asset {
...ReplyListContainer4_asset
@@ -300,6 +322,12 @@ const ReplyListContainer2 = createReplyListContainer(
...CommentContainer_me
}
`,
settings: graphql`
fragment ReplyListContainer2_settings on Settings {
...ReplyListContainer3_settings
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer2_asset on Asset {
...ReplyListContainer3_asset
@@ -354,6 +382,12 @@ const ReplyListContainer1 = createReplyListContainer(
...CommentContainer_me
}
`,
settings: graphql`
fragment ReplyListContainer1_settings on Settings {
...ReplyListContainer2_settings
...CommentContainer_settings
}
`,
asset: graphql`
fragment ReplyListContainer1_asset on Asset {
...ReplyListContainer2_asset
@@ -5,6 +5,7 @@ import { withPaginationContainer } from "talk-framework/lib/relay";
import { PropTypesOf } from "talk-framework/types";
import { StreamContainer_asset as AssetData } from "talk-stream/__generated__/StreamContainer_asset.graphql";
import { StreamContainer_me as MeData } from "talk-stream/__generated__/StreamContainer_me.graphql";
import { StreamContainer_settings as SettingsData } from "talk-stream/__generated__/StreamContainer_settings.graphql";
import {
COMMENT_SORT,
StreamContainerPaginationQueryVariables,
@@ -14,6 +15,7 @@ import Stream from "../components/Stream";
interface InnerProps {
asset: AssetData;
settings: SettingsData;
me: MeData | null;
relay: RelayPaginationProp;
}
@@ -38,6 +40,7 @@ export class StreamContainer extends React.Component<InnerProps> {
<Stream
asset={this.props.asset}
comments={comments}
settings={this.props.settings}
onLoadMore={this.loadMore}
hasMore={this.props.relay.hasMore()}
disableLoadMore={this.state.disableLoadMore}
@@ -105,6 +108,12 @@ const enhanced = withPaginationContainer<
...UserBoxContainer_me
}
`,
settings: graphql`
fragment StreamContainer_settings on Settings {
...ReplyListContainer1_settings
...CommentContainer_settings
}
`,
},
{
direction: "forward",
@@ -36,6 +36,7 @@ export const render = ({
return (
<PermalinkViewContainer
me={props.me}
settings={props.settings}
comment={props.comment}
asset={props.asset}
/>
@@ -63,6 +64,9 @@ const PermalinkViewQuery: StatelessComponent<InnerProps> = ({
comment(id: $commentID) {
...PermalinkViewContainer_comment
}
settings {
...PermalinkViewContainer_settings
}
}
`}
variables={{
@@ -31,7 +31,13 @@ export const render = ({
</Localized>
);
}
return <StreamContainer me={props.me} asset={props.asset} />;
return (
<StreamContainer
settings={props.settings}
me={props.me}
asset={props.asset}
/>
);
}
return <Spinner />;
@@ -49,6 +55,9 @@ const StreamQuery: StatelessComponent<InnerProps> = ({
asset(id: $assetID, url: $assetURL) {
...StreamContainer_asset
}
settings {
...StreamContainer_settings
}
}
`}
variables={{
@@ -498,15 +498,31 @@ ReactionConfiguration stores the configuration for reactions used across this
Tenant.
"""
type ReactionConfiguration {
"""
icon is the string representing the icon to be used for the reactions.
"""
icon: String!
"""
"""
iconActive: String
"""
label is the string placed beside the reaction icon to provide better context.
"""
label: String!
"""
icon is the string representing the icon to be used for the reactions.
labelActive is the string placed beside the reaction icon to provide better
context when it has been selected.
"""
icon: String!
labelActive: String
"""
color is the hex color code that can be used to change the color of the button.
"""
color: String
}
################################################################################
@@ -653,7 +669,7 @@ type Settings {
"""
reaction specifies the configuration for reactions.
"""
reaction: ReactionConfiguration! @auth(roles: [ADMIN])
reaction: ReactionConfiguration!
}
################################################################################
+2 -1
View File
@@ -121,7 +121,8 @@ export async function createTenant(mongo: Db, input: CreateTenantInput) {
// By default, the standard reaction style will use the Respect with the
// handshake.
label: "Respect",
icon: "handshake",
labelActive: "Respected",
icon: "thumb_up",
},
};
-3
View File
@@ -68,6 +68,3 @@ comments-editCommentForm-rte =
comments-editCommentForm-editRemainingTime = Edit: <time></time> remaining
comments-editCommentForm-editTimeExpired = Edit time has expired. You can no longer edit this comment. Why not post another one?
comments-editedMarker-edited = Edited
comments-respectButton-respect = Respect
comments-respectButton-respected = Respected