diff --git a/app/javascript/mastodon/components/account_header/buttons.tsx b/app/javascript/mastodon/components/account_header/buttons.tsx
index c66ae9b0892..594e27e2bd7 100644
--- a/app/javascript/mastodon/components/account_header/buttons.tsx
+++ b/app/javascript/mastodon/components/account_header/buttons.tsx
@@ -1,11 +1,13 @@
import { useCallback } from 'react';
import type { FC } from 'react';
-import { defineMessages, useIntl } from 'react-intl';
+import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
-import { BellIcon, BellSlashIcon } from '@phosphor-icons/react';
+import { ChatCircleDotsIcon, UserMinusIcon } from '@phosphor-icons/react';
import { followAccount } from '@/mastodon/actions/accounts';
+import { directCompose } from '@/mastodon/actions/compose';
+import { openModal } from '@/mastodon/actions/modal';
import { useAccount } from '@/mastodon/hooks/useAccount';
import { useFollowReference } from '@/mastodon/hooks/useFollowReference';
import { getAccountHidden } from '@/mastodon/selectors/accounts';
@@ -14,7 +16,7 @@ import { isRedesignEnabled } from '@/mastodon/utils/environment';
import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react';
import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react';
-import { ToggleIconButton } from '../button/redesign';
+import { Button, IconButton } from '../button/redesign';
import { CopyIconButton, CopyIconButtonLegacy } from '../copy_button';
import { FollowButton } from '../follow_button';
import { IconButton as LegacyIconButton } from '../icon_button';
@@ -71,12 +73,27 @@ const AccountButtonsOther: FC<
);
const dispatch = useAppDispatch();
+
const handleNotifyToggle = useCallback(() => {
if (account) {
dispatch(followAccount(account.id, { notify: !relationship?.notifying }));
}
}, [dispatch, account, relationship]);
+ const sendDirectMessage = useCallback(() => {
+ if (account) {
+ dispatch(directCompose(account));
+ }
+ }, [dispatch, account]);
+
+ const confirmUnfollow = useCallback(() => {
+ if (account) {
+ dispatch(
+ openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }),
+ );
+ }
+ }, [dispatch, account]);
+
const reference = useFollowReference('profile');
if (!account) {
@@ -86,9 +103,11 @@ const AccountButtonsOther: FC<
const isMovedAndUnfollowedAccount = account.moved && !relationship?.following;
const isFollowing = relationship?.requested || relationship?.following;
+ const shouldHideMainFollowButton = isRedesignEnabled() && isFollowing;
+
return (
<>
- {!isMovedAndUnfollowedAccount && (
+ {!shouldHideMainFollowButton && !isMovedAndUnfollowedAccount && (
)}
- {isFollowing &&
- (isRedesignEnabled() ? (
-
+
- ) : (
-
- ))}
+
+
+
+
+
+ >
+ )}
+ {isFollowing && !isRedesignEnabled() && (
+
+ )}
{!noShare &&
(isRedesignEnabled() ? (
{
- dispatch(directCompose(account));
- },
- });
+ if (!relationship?.following) {
+ items.push(null, {
+ text: intl.formatMessage(messages.redesignMessage),
+ action: () => {
+ dispatch(directCompose(account));
+ },
+ });
+ }
} else {
items.push(
+ null,
{
text: intl.formatMessage(messages.mention),
action: () => {
@@ -400,6 +410,21 @@ function getMenuItems({
// Timeline options
if (relationship?.following && !relationship.muting) {
+ if (isRedesignEnabled()) {
+ items.push({
+ text: intl.formatMessage(
+ relationship.notifying
+ ? messages.disableNotifications
+ : messages.enableNotifications,
+ { name: account.username },
+ ),
+ action: () => {
+ dispatch(
+ followAccount(account.id, { notify: !relationship.notifying }),
+ );
+ },
+ });
+ }
items.push(
{
text: intl.formatMessage(
diff --git a/app/javascript/mastodon/components/follow_button.tsx b/app/javascript/mastodon/components/follow_button.tsx
index ec6c7896c4c..165ddd16e38 100644
--- a/app/javascript/mastodon/components/follow_button.tsx
+++ b/app/javascript/mastodon/components/follow_button.tsx
@@ -5,6 +5,9 @@ import { useIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import { Link } from 'react-router-dom';
+import type { Icon } from '@phosphor-icons/react';
+import { UserMinusIcon, UserPlusIcon } from '@phosphor-icons/react';
+
import { useIdentity } from '@/mastodon/identity_context';
import {
fetchRelationships,
@@ -69,6 +72,7 @@ interface FollowButtonOptions {
interface FollowButtonReturn {
label: React.ReactNode;
+ icon: Icon | undefined;
onClick: (() => void) | undefined;
link: MastodonLocationDescriptor | undefined;
disabled: boolean;
@@ -163,11 +167,13 @@ export function useFollowButton({
: messages.follow;
let label: React.ReactNode;
+ let icon: Icon | undefined;
let disabled =
relationship?.blocked_by || account?.suspended || !!account?.moved;
if (!signedIn) {
label = intl.formatMessage(followMessage);
+ icon = UserPlusIcon;
} else if (accountId === me) {
label = intl.formatMessage(messages.editProfile);
} else if (!relationship) {
@@ -177,6 +183,7 @@ export function useFollowButton({
disabled = false;
} else if (relationship.following) {
label = intl.formatMessage(messages.unfollow);
+ icon = UserMinusIcon;
disabled = false;
} else if (relationship.blocking) {
label = intl.formatMessage(messages.unblock);
@@ -186,8 +193,10 @@ export function useFollowButton({
disabled = false;
} else if (relationship.followed_by && !account?.locked) {
label = intl.formatMessage(messages.followBack);
+ icon = UserPlusIcon;
} else {
label = intl.formatMessage(followMessage);
+ icon = UserPlusIcon;
}
const isMovedAndUnfollowedAccount =
@@ -197,6 +206,7 @@ export function useFollowButton({
onClick,
link,
label,
+ icon,
disabled,
following,
secondary,
@@ -242,22 +252,28 @@ const FollowButtonRedesign: React.FC<
FollowButtonOptions &
Pick
> = ({ accountId, labelLength, withUnmute, reference, ...buttonProps }) => {
- const { onClick, link, label, disabled, secondary, hidden } = useFollowButton(
- {
+ const { onClick, link, label, icon, disabled, secondary, hidden } =
+ useFollowButton({
accountId,
labelLength,
withUnmute,
reference,
- },
- );
+ });
if (hidden) {
return null;
}
+ const leadingIcon = labelLength === 'long' ? icon : undefined;
+
if (link) {
return (
-
+
{label}
);
@@ -266,6 +282,7 @@ const FollowButtonRedesign: React.FC<
return (