Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add block user option on post context menu #4053

Merged
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5a17ffe
feat: ReportUserModal
AmarTrebinjac Jan 7, 2025
0540f79
formatting
AmarTrebinjac Jan 8, 2025
8be4262
lint
AmarTrebinjac Jan 8, 2025
eef302c
remove unnecessary check
AmarTrebinjac Jan 8, 2025
63e5977
update conditional
AmarTrebinjac Jan 8, 2025
88066b5
Merge branch 'MI-741' of https://github.com/dailydotdev/apps into MI-…
ilasw Jan 8, 2025
08de8e0
feat: add block user option in post context menu
ilasw Jan 8, 2025
aa74858
remove need to pass onClose
AmarTrebinjac Jan 8, 2025
9b01e41
capitalize values
AmarTrebinjac Jan 8, 2025
aecc124
Merge branch 'MI-741' of https://github.com/dailydotdev/apps into MI-…
ilasw Jan 9, 2025
4388eb2
feat: add optimistic update on unblock
ilasw Jan 9, 2025
02706e2
Merge branch 'MI-655-report-and-block-user' of https://github.com/dai…
ilasw Jan 9, 2025
f9f7bbc
Merge branch 'MI-655-report-and-block-user' of https://github.com/dai…
ilasw Jan 9, 2025
0271bc1
feat: refactor avoiding additional query
ilasw Jan 9, 2025
3d6d522
fix: ssr error
ilasw Jan 9, 2025
b2ac887
Merge branch 'MI-655-report-and-block-user' into MI-717-block-user-on…
ilasw Jan 9, 2025
a8194bf
feat: add contentPreference data for author
ilasw Jan 9, 2025
a190049
Merge branch 'MI-655-report-and-block-user' into MI-717-block-user-on…
ilasw Jan 13, 2025
a4d967d
Merge branch 'MI-717-block-user-on-post-context-menu' of https://gith…
ilasw Jan 14, 2025
e3dd167
Merge branch 'MI-655-report-and-block-user' of https://github.com/dai…
ilasw Jan 14, 2025
7abf0c8
feat: hide follow option for blocked users, change source block label;
ilasw Jan 14, 2025
50466d5
feat: clear cache on block
ilasw Jan 14, 2025
fcb8a0d
Merge branch 'MI-655-report-and-block-user' into MI-717-block-user-on…
ilasw Jan 14, 2025
1fd60e5
feat: block on custom feed feature
ilasw Jan 14, 2025
921f5cf
Merge remote-tracking branch 'origin/MI-717-block-user-on-post-contex…
ilasw Jan 14, 2025
ed004e1
test: update label for block/unblock
ilasw Jan 14, 2025
38898f5
Merge branch 'MI-655-report-and-block-user' into MI-717-block-user-on…
ilasw Jan 16, 2025
adbb414
refactor: invalidate cache is not a utility
ilasw Jan 16, 2025
10cdb3d
feat: added new labels and block directly without report modal
ilasw Jan 16, 2025
63da103
Merge branch 'MI-655-report-and-block-user' into MI-717-block-user-on…
ilasw Jan 16, 2025
8a92e2f
feat: hide post from feed and add undo action to toast
ilasw Jan 16, 2025
7a582eb
Merge remote-tracking branch 'origin/MI-717-block-user-on-post-contex…
ilasw Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/shared/src/components/Feed.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ describe('Feed logged in', () => {
);
expect(data).toBeTruthy();
});
const contextBtn = await screen.findByText("Don't show posts from Echo JS");
const contextBtn = await screen.findByText('Block Echo JS');
fireEvent.click(contextBtn);
await waitForNock();
await waitFor(() => expect(mutationCalled).toBeTruthy());
Expand Down Expand Up @@ -673,7 +673,7 @@ describe('Feed logged in', () => {
);
expect(data).toBeTruthy();
});
const contextBtn = await screen.findByText('Show posts from Echo JS');
const contextBtn = await screen.findByText('Unblock Echo JS');

await waitFor(async () => {
fireEvent.click(contextBtn);
Expand Down
87 changes: 66 additions & 21 deletions packages/shared/src/components/PostOptionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ import classNames from 'classnames';
import useFeedSettings from '../hooks/useFeedSettings';
import useReportPost from '../hooks/useReportPost';
import type { Post } from '../graphql/posts';
import { UserVote, isVideoPost } from '../graphql/posts';
import { isVideoPost, UserVote } from '../graphql/posts';
import {
TrashIcon,
HammerIcon,
EyeIcon,
AddUserIcon,
BellAddIcon,
BellSubscribedIcon,
BlockIcon,
FlagIcon,
PlusIcon,
EditIcon,
UpvoteIcon,
DownvoteIcon,
SendBackwardIcon,
BringForwardIcon,
PinIcon,
BellSubscribedIcon,
ShareIcon,
DownvoteIcon,
EditIcon,
EyeIcon,
FlagIcon,
FolderIcon,
HammerIcon,
MiniCloseIcon,
MinusIcon,
BellAddIcon,
AddUserIcon,
PinIcon,
PlusIcon,
RemoveUserIcon,
FolderIcon,
SendBackwardIcon,
ShareIcon,
ShieldIcon,
ShieldWarningIcon,
TrashIcon,
UpvoteIcon,
} from './icons';
import type { ReportedCallback } from './modals';
import useTagAndSource from '../hooks/useTagAndSource';
Expand Down Expand Up @@ -63,7 +63,10 @@ import { useBookmarkReminder } from '../hooks/notifications';
import { BookmarkReminderIcon } from './icons/Bookmark/Reminder';
import { useSourceActionsFollow } from '../hooks/source/useSourceActionsFollow';
import { useContentPreference } from '../hooks/contentPreference/useContentPreference';
import { ContentPreferenceType } from '../graphql/contentPreference';
import {
ContentPreferenceStatus,
ContentPreferenceType,
} from '../graphql/contentPreference';
import { isFollowingContent } from '../hooks/contentPreference/types';
import { useIsSpecialUser } from '../hooks/auth/useIsSpecialUser';
import { useActiveFeedContext } from '../contexts';
Expand Down Expand Up @@ -135,8 +138,7 @@ export default function PostOptionsMenu({
const { logEvent } = useContext(LogContext);
const { hidePost, unhidePost } = useReportPost();
const { openSharePost } = useSharePost(origin);
const { follow, unfollow } = useContentPreference();

const { follow, unfollow, unblock } = useContentPreference();
const { openModal } = useLazyModal();

const {
Expand All @@ -156,6 +158,8 @@ export default function PostOptionsMenu({
(excludedSource) => excludedSource.id === post?.source?.id,
);
}, [feedSettings?.excludeSources, post?.source?.id]);
const isBlockedAuthor =
post?.author?.contentPreference?.status === ContentPreferenceStatus.Blocked;

const shouldShowSubscribe =
isLoggedIn &&
Expand Down Expand Up @@ -456,6 +460,7 @@ export default function PostOptionsMenu({
const shouldShowFollow =
!useIsSpecialUser({ userId: post?.author?.id }) &&
post?.author &&
!isBlockedAuthor &&
isLoggedIn;

if (shouldShowFollow) {
Expand Down Expand Up @@ -495,11 +500,51 @@ export default function PostOptionsMenu({
postOptions.push({
icon: <MenuIcon Icon={BlockIcon} />,
label: isSourceBlocked
? `Show posts from ${post?.source?.name}`
: `Don't show posts from ${post?.source?.name}`,
? `Unblock ${post?.source?.name}`
: `Block ${post?.source?.name}`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like the Block can be misleading that it will block the source across the board. Maybe saying "Block Source from this Feed" or something similar. Either way, this is non-blocking. Just some thought about the new labe.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I've raised the issue as well before. I don't like that we use the same wording for a global block and just removing someone of a feed!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change comes from the slack thread in description, but feel free to propose some changes in slack and I can change in minutes ✔️

action: isSourceBlocked ? onUnblockSourceClick : onBlockSourceClick,
});

if (post?.author && post?.author?.id !== user?.id) {
postOptions.push({
icon: <MenuIcon Icon={BlockIcon} />,
label: isBlockedAuthor
? `Unblock ${post.author.name}`
: `Block ${post.author.name}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be different my feed vs custom feed but raised it here.
https://dailydotdev.slack.com/archives/C07GVUM114N/p1737018718495219?thread_ts=1736422027.072149&cid=C07GVUM114N

action: async () => {
const clearCache = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe best to abstract this above in it's own function for readability?
(non blocking)

const postQueryKey = getPostByIdKey(post.id);
const postCache = client.getQueryData(postQueryKey);
if (postCache) {
client.invalidateQueries({ queryKey: postQueryKey });
}
};

if (!isBlockedAuthor) {
openModal({
type: LazyModal.ReportUser,
props: {
offendingUser: post.author,
defaultBlockUser: true,
onBlockUser: clearCache,
...(isCustomFeed && { feedId: customFeedId }),
},
});
return;
}

await unblock({
id: post.author.id,
entity: ContentPreferenceType.User,
entityName: post.author.name,
feedId: router.query.slugOrId ? `${router.query.slugOrId}` : null,
});

clearCache();
},
});
}

if (video && isVideoPost(post)) {
const isEnabled = checkSettingsEnabledState(video.id);
const label = isEnabled ? `Don't show` : 'Show';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ const reportReasons: { value: string; label: string }[] = [
];

type ReportUserModalProps = {
offendingUser: Pick<UserShortProfile, 'id' | 'username'>;
defaultBlockUser?: boolean;
feedId?: string;
offendingUser: Pick<UserShortProfile, 'id' | 'username'>;
onBlockUser?: () => void;
};

export const ReportUserModal = ({
offendingUser,
defaultBlockUser,
feedId,
onBlockUser,
}: ReportUserModalProps): ReactElement => {
const { closeModal: onClose } = useLazyModal();
const { displayToast } = useToastNotification();
Expand All @@ -47,11 +51,12 @@ export const ReportUserModal = ({
gqlClient.request(CONTENT_PREFERENCE_BLOCK_MUTATION, {
id: offendingUser.id,
entity: ContentPreferenceType.User,
feedId: user?.id,
feedId: feedId ?? user?.id,
}),
onSuccess: () => {
displayToast(`🚫 ${offendingUser.username} has been blocked`);
onClose();
onBlockUser?.();
},
onError: () => {
displayToast(`❌ Failed to block ${offendingUser.username}`);
Expand Down
3 changes: 3 additions & 0 deletions packages/shared/src/graphql/fragments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ export const FEED_POST_INFO_FRAGMENT = gql`
image
username
permalink
contentPreference {
status
}
}
type
tags
Expand Down
Loading