Skip to content

Commit

Permalink
Disable thread actions for users that have not joined the community (#…
Browse files Browse the repository at this point in the history
…4521)

* Quill initial work

* Add monospace font on markdown

* Add focus styles

* Add disabled state

* prevent jump between markdown toggle

* Adjust quill all over the app

* Update icons to phosphor

* Add quill to component showcase

* Remove placeholder default text

* Add banner component

* Add static banner to view thread page

* Add static banner to create thread page

* Add closing banner in new thread form

* Add closing banner in discussion page

* Abstract join community logic into hook

* use join community hook in new thread form

* use join community hook in view thread page

* use hook for check active account

* use hook for closing banner logic

* abstract AccountSelectorModal

* abstract TOS modal

* abstract all join community modals modals

* rename old banner and create new component for join community banner

* Fix ts errors

* Revert merge changes

* Disable editor 4377

* Change naming

* Change naming pt. 2

* Change naming pt. 3

* Unify small upvote button

* Remove upvote from thread action component

* Replace comment button

* Replace share button

* Replace subscribe btn

* Replace overflow btn

* add upvote to thread action component

* Change div to button

* Progress on disabling

* Add tooltip wrapper to thread action

* Edit tooltip styles to adjust new designs

* Add tooltip to disabled buttons

* Handle reply button

* Fix create thread buttons

* self CR

* fixed lint errors

* remove comment

* conflicts

---------

Co-authored-by: Marcin Maslanka <[email protected]>
Co-authored-by: Muon Shot <[email protected]>
  • Loading branch information
3 people authored and dillchen committed Jul 30, 2023
1 parent b2cf40c commit 7d5a698
Show file tree
Hide file tree
Showing 46 changed files with 1,758 additions and 1,933 deletions.
Original file line number Diff line number Diff line change
@@ -1,52 +1,47 @@
import 'components/ReactionButton/CommentReactionButton.scss';
import { notifyError } from 'controllers/app/notifications';
import React, { useState, useEffect } from 'react';
import { notifyError } from 'controllers/app/notifications';
import app from 'state';
import type ChainInfo from '../../../models/ChainInfo';
import type Comment from '../../../models/Comment';
import ReactionCount from '../../../models/ReactionCount';
import {
useCreateCommentReactionMutation,
useDeleteCommentReactionMutation,
useFetchCommentReactionsQuery
useFetchCommentReactionsQuery,
} from '../../../state/api/comments';
import Permissions from '../../../utils/Permissions';
import { LoginModal } from '../../modals/login_modal';
import { CWIcon } from '../component_kit/cw_icons/cw_icon';
import { Modal } from '../component_kit/cw_modal';
import { CWTooltip } from '../component_kit/cw_popover/cw_tooltip';
import {
getClasses,
isWindowMediumSmallInclusive,
} from '../component_kit/helpers';
import {
getDisplayedReactorsForPopup,
onReactionClick,
} from './helpers';
import { isWindowMediumSmallInclusive } from '../component_kit/helpers';
import { getDisplayedReactorsForPopup, onReactionClick } from './helpers';
import CWUpvoteSmall from 'views/components/component_kit/new_designs/CWUpvoteSmall';

type CommentReactionButtonProps = {
comment: Comment<any>;
disabled: boolean;
};

export const CommentReactionButton = ({
comment,
disabled,
}: CommentReactionButtonProps) => {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [reactors, setReactors] = useState<Array<any>>([]);
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const [reactionCounts, setReactionCounts] = useState<ReactionCount<any>>();
const { mutateAsync: createCommentReaction } = useCreateCommentReactionMutation({
commentId: comment.id,
chainId: app.activeChainId()
})
const { mutateAsync: deleteCommentReaction } = useDeleteCommentReactionMutation({
commentId: comment.id,
chainId: app.activeChainId()
})
const { mutateAsync: createCommentReaction } =
useCreateCommentReactionMutation({
commentId: comment.id,
chainId: app.activeChainId(),
});
const { mutateAsync: deleteCommentReaction } =
useDeleteCommentReactionMutation({
commentId: comment.id,
chainId: app.activeChainId(),
});
const { data: reactions } = useFetchCommentReactionsQuery({
chainId: app.activeChainId(),
commentId: comment.id,
})
});

useEffect(() => {
const redrawFunction = (comment_id) => {
Expand Down Expand Up @@ -82,8 +77,6 @@ export const CommentReactionButton = ({
return r.Address.address === activeAddress;
});

setIsLoading(true);

deleteCommentReaction({
canvasHash: foundReaction.canvas_hash,
reactionId: foundReaction.id,
Expand All @@ -92,34 +85,49 @@ export const CommentReactionButton = ({
likes: likes - 1,
hasReacted: false,
},
}).then(() => {
setReactors(
reactors.filter(({ Address }) => Address.address !== userAddress)
);
setReactionCounts(app.comments.reactionCountsStore.getByPost(comment));
setIsLoading(false);
}).catch(() => {
notifyError('Failed to update reaction count');
});
})
.then(() => {
setReactors(
reactors.filter(({ Address }) => Address.address !== userAddress)
);
setReactionCounts(app.comments.reactionCountsStore.getByPost(comment));
})
.catch(() => {
notifyError('Failed to update reaction count');
});
};

const like = (chain: ChainInfo, chainId: string, userAddress: string) => {
setIsLoading(true);

createCommentReaction({
address: userAddress,
commentId: comment.id,
chainId: chainId,
}).then(() => {
setReactors([
...reactors,
{ Address: { address: userAddress, chain } },
]);
setReactionCounts(app.comments.reactionCountsStore.getByPost(comment));
setIsLoading(false);
}).catch(() => {
notifyError('Failed to save reaction');
})
.then(() => {
setReactors([
...reactors,
{ Address: { address: userAddress, chain } },
]);
setReactionCounts(app.comments.reactionCountsStore.getByPost(comment));
})
.catch(() => {
notifyError('Failed to save reaction');
});
};

const handleVoteClick = async (e) => {
e.stopPropagation();
e.preventDefault();

if (!app.isLoggedIn() || !app.user.activeAccount) {
setIsModalOpen(true);
} else {
onReactionClick(e, hasReacted, dislike, like);
}
};

const handleVoteMouseEnter = async () => {
setReactors(reactions);
};

return (
Expand All @@ -130,66 +138,16 @@ export const CommentReactionButton = ({
onClose={() => setIsModalOpen(false)}
open={isModalOpen}
/>
<button
className={getClasses<{ disabled?: boolean }>(
{ disabled: isLoading || isUserForbidden },
`CommentReactionButton ${hasReacted ? ' has-reacted' : ''}`
)}
// TODO: won't be needed now?
onMouseEnter={async () => {
setReactors(reactions);
}}
onClick={async (e) => {
e.stopPropagation();
e.preventDefault();

if (!app.isLoggedIn() || !app.user.activeAccount) {
setIsModalOpen(true);
} else {
onReactionClick(e, hasReacted, dislike, like);
}
}}
>
{likes > 0 ? (
<CWTooltip
content={
<div className="reaction-button-tooltip-contents">
{getDisplayedReactorsForPopup({
reactors: reactors.map((r) => r.Address.address),
})}
</div>
}
renderTrigger={(handleInteraction) => (
<div
onMouseEnter={handleInteraction}
onMouseLeave={handleInteraction}
className="btn-container"
>
<CWIcon
iconName="upvote"
iconSize="small"
{...(hasReacted && { weight: 'fill' })}
/>
<div
className={`reactions-count ${hasReacted ? ' has-reacted' : ''
}`}
>
{likes}
</div>
</div>
)}
/>
) : (
<>
<CWIcon iconName="upvote" iconSize="small" />
<div
className={`reactions-count ${hasReacted ? ' has-reacted' : ''}`}
>
{likes}
</div>
</>
)}
</button>
<CWUpvoteSmall
voteCount={likes}
disabled={isUserForbidden || disabled}
selected={hasReacted}
onMouseEnter={handleVoteMouseEnter}
onClick={handleVoteClick}
tooltipContent={getDisplayedReactorsForPopup({
reactors: reactors.map((r) => r.Address.address),
})}
/>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -1024,8 +1024,7 @@ export const ComponentShowcase = () => {
/>
<CWThreadAction
action="upvote"
count={1}
onClick={() => console.log('Upvote action clicked!!')}
onClick={() => console.log('Upvote action clicked!')}
/>
<CWThreadAction
action="overflow"
Expand All @@ -1049,7 +1048,6 @@ export const ComponentShowcase = () => {
/>
<CWThreadAction
action="upvote"
count={1}
onClick={() => console.log('Upvote action clicked!')}
disabled
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import MinimumProfile from '../../../models/MinimumProfile';
import { Thread } from '../../../models/Thread';
import Topic from '../../../models/Topic';
import { ThreadStage } from '../../../models/types';
import { AuthorAndPublishInfo as ThreadAuthorAndPublishInfo } from '../../pages/discussions/ThreadCard/AuthorAndPublishInfo';
import { Options as ThreadOptions } from '../../pages/discussions/ThreadCard/Options';
import { AuthorAndPublishInfo } from '../../pages/discussions/ThreadCard/AuthorAndPublishInfo';
import { ThreadOptions } from '../../pages/discussions/ThreadCard/ThreadOptions';
import { CWCard } from './cw_card';
import { CWTab, CWTabBar } from './cw_tabs';
import { CWText } from './cw_text';
Expand Down Expand Up @@ -116,7 +116,7 @@ export const CWContentPage = ({
title
)}
<div className="header-info-row">
<ThreadAuthorAndPublishInfo
<AuthorAndPublishInfo
showSplitDotIndicator={true}
isNew={!!displayNewTag}
isLocked={thread?.readOnly}
Expand Down Expand Up @@ -156,8 +156,8 @@ export const CWContentPage = ({
{body &&
body(
<ThreadOptions
canVote={!thread?.readOnly}
canComment={!thread?.readOnly}
upvoteBtnVisible={!thread?.readOnly}
commentBtnVisible={!thread?.readOnly}
thread={thread}
totalComments={thread?.numberOfComments}
onLockToggle={onLockToggle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type UsePopoverProps = {
type PopoverProps = {
content: React.ReactNode;
placement?: Placement;
disablePortal?: boolean;
} & UsePopoverProps;

export type PopoverTriggerProps = {
Expand Down Expand Up @@ -44,14 +45,20 @@ export const usePopover = (): UsePopoverProps => {
};
};

export const Popover = (props: PopoverProps) => {
const { anchorEl, content, id, open, placement } = props;

export const Popover = ({
anchorEl,
content,
id,
open,
placement,
disablePortal,
}: PopoverProps) => {
return (
<PopperUnstyled
id={id}
open={open}
anchorEl={anchorEl}
disablePortal={disablePortal}
placement={placement || 'bottom-start'}
modifiers={[
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,23 @@ type TooltipProps = {
content: string | React.ReactNode;
hasBackground?: boolean;
placement?: Placement;
disablePortal?: boolean;
} & PopoverTriggerProps;

export const CWTooltip = (props: TooltipProps) => {
const { content, hasBackground, renderTrigger, placement } = props;

export const CWTooltip = ({
content,
hasBackground,
renderTrigger,
placement,
disablePortal,
}: TooltipProps) => {
const popoverProps = usePopover();

return (
<>
{renderTrigger(popoverProps.handleInteraction)}
<Popover
disablePortal={disablePortal}
placement={placement}
content={
typeof content === 'string' ? (
Expand Down
Loading

0 comments on commit 7d5a698

Please sign in to comment.