Merge remote-tracking branch 'parent/main' into upstream-20250414

This commit is contained in:
KMY 2025-04-14 13:23:00 +09:00
commit dba5f3b93f
208 changed files with 3210 additions and 2896 deletions

View file

@ -1,6 +1,6 @@
import type { ReactNode } from 'react';
import type React from 'react';
import { useCallback } from 'react';
import { useCallback, useMemo } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
@ -14,18 +14,19 @@ import {
muteAccount,
unmuteAccount,
} from 'mastodon/actions/accounts';
import { openModal } from 'mastodon/actions/modal';
import { initMuteModal } from 'mastodon/actions/mutes';
import { Avatar } from 'mastodon/components/avatar';
import { Button } from 'mastodon/components/button';
import { FollowersCounter } from 'mastodon/components/counters';
import { DisplayName } from 'mastodon/components/display_name';
import { Dropdown } from 'mastodon/components/dropdown_menu';
import { FollowButton } from 'mastodon/components/follow_button';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
import { ShortNumber } from 'mastodon/components/short_number';
import { Skeleton } from 'mastodon/components/skeleton';
import { VerifiedBadge } from 'mastodon/components/verified_badge';
import DropdownMenu from 'mastodon/containers/dropdown_menu_container';
import { me } from 'mastodon/initial_state';
import type { MenuItem } from 'mastodon/models/dropdown_menu';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
const messages = defineMessages({
@ -48,6 +49,14 @@ const messages = defineMessages({
mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
block: { id: 'account.block_short', defaultMessage: 'Block' },
more: { id: 'status.more', defaultMessage: 'More' },
addToLists: {
id: 'account.add_or_remove_from_list',
defaultMessage: 'Add or Remove from lists',
},
openOriginalPage: {
id: 'account.open_original_page',
defaultMessage: 'Open original page',
},
});
export const Account: React.FC<{
@ -73,6 +82,7 @@ export const Account: React.FC<{
const account = useAppSelector((state) => state.accounts.get(id));
const relationship = useAppSelector((state) => state.relationships.get(id));
const dispatch = useAppDispatch();
const accountUrl = account?.url;
const handleBlock = useCallback(() => {
if (relationship?.blocking) {
@ -90,13 +100,62 @@ export const Account: React.FC<{
}
}, [dispatch, id, account, relationship]);
const handleMuteNotifications = useCallback(() => {
dispatch(muteAccount(id, true));
}, [dispatch, id]);
const menu = useMemo(() => {
let arr: MenuItem[] = [];
const handleUnmuteNotifications = useCallback(() => {
dispatch(muteAccount(id, false));
}, [dispatch, id]);
if (defaultAction === 'mute') {
const handleMuteNotifications = () => {
dispatch(muteAccount(id, true));
};
const handleUnmuteNotifications = () => {
dispatch(muteAccount(id, false));
};
arr = [
{
text: intl.formatMessage(
relationship?.muting_notifications
? messages.unmute_notifications
: messages.mute_notifications,
),
action: relationship?.muting_notifications
? handleUnmuteNotifications
: handleMuteNotifications,
},
];
} else if (defaultAction !== 'block') {
const handleAddToLists = () => {
dispatch(
openModal({
modalType: 'LIST_ADDER',
modalProps: {
accountId: id,
},
}),
);
};
arr = [
{
text: intl.formatMessage(messages.addToLists),
action: handleAddToLists,
},
];
if (accountUrl) {
arr.unshift(
{
text: intl.formatMessage(messages.openOriginalPage),
href: accountUrl,
},
null,
);
}
}
return arr;
}, [dispatch, intl, id, accountUrl, relationship, defaultAction]);
if (hidden) {
return (
@ -107,73 +166,46 @@ export const Account: React.FC<{
);
}
let buttons;
let button: React.ReactNode, dropdown: React.ReactNode;
if (account && account.id !== me && relationship) {
const { requested, blocking, muting } = relationship;
if (menu.length > 0) {
dropdown = (
<Dropdown
items={menu}
icon='ellipsis-h'
iconComponent={MoreHorizIcon}
title={intl.formatMessage(messages.more)}
/>
);
}
if (requested) {
buttons = <FollowButton accountId={id} />;
} else if (blocking) {
buttons = (
<Button
text={intl.formatMessage(messages.unblock)}
onClick={handleBlock}
/>
);
} else if (muting) {
const menu = [
{
text: intl.formatMessage(
relationship.muting_notifications
? messages.unmute_notifications
: messages.mute_notifications,
),
action: relationship.muting_notifications
? handleUnmuteNotifications
: handleMuteNotifications,
},
];
buttons = (
<>
<DropdownMenu
items={menu}
icon='ellipsis-h'
iconComponent={MoreHorizIcon}
direction='right'
title={intl.formatMessage(messages.more)}
/>
<Button
text={intl.formatMessage(messages.unmute)}
onClick={handleMute}
/>
</>
);
} else if (defaultAction === 'mute') {
buttons = (
<Button text={intl.formatMessage(messages.mute)} onClick={handleMute} />
);
} else if (defaultAction === 'block') {
buttons = (
<Button
text={intl.formatMessage(messages.block)}
onClick={handleBlock}
/>
);
} else {
buttons = <FollowButton accountId={id} />;
}
if (defaultAction === 'block') {
button = (
<Button
text={intl.formatMessage(
relationship?.blocking ? messages.unblock : messages.block,
)}
onClick={handleBlock}
/>
);
} else if (defaultAction === 'mute') {
button = (
<Button
text={intl.formatMessage(
relationship?.muting ? messages.unmute : messages.mute,
)}
onClick={handleMute}
/>
);
} else {
buttons = <FollowButton accountId={id} />;
button = <FollowButton accountId={id} />;
}
if (hideButtons) {
buttons = null;
button = null;
}
let muteTimeRemaining;
let muteTimeRemaining: React.ReactNode;
if (account?.mute_expires_at) {
muteTimeRemaining = (
@ -183,7 +215,7 @@ export const Account: React.FC<{
);
}
let verification;
let verification: React.ReactNode;
const firstVerifiedField = account?.fields.find((item) => !!item.verified_at);
@ -233,11 +265,17 @@ export const Account: React.FC<{
{!minimal && children && (
<div>
<div>{children}</div>
<div className='account__relationship'>{buttons}</div>
<div className='account__relationship'>
{dropdown}
{button}
</div>
</div>
)}
{!minimal && !children && (
<div className='account__relationship'>{buttons}</div>
<div className='account__relationship'>
{dropdown}
{button}
</div>
)}
</div>