Merge commit 'cfb473c204' into upstream-20250228

This commit is contained in:
KMY 2025-02-28 11:07:08 +09:00
commit 795561f5a7
78 changed files with 1684 additions and 1081 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,175 +0,0 @@
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import InnerHeader from '../../account/components/header';
import MemorialNote from './memorial_note';
import MovedNote from './moved_note';
class Header extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.record,
featuredTags: PropTypes.array,
onFollow: PropTypes.func.isRequired,
onBlock: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired,
onDirect: PropTypes.func.isRequired,
onReblogToggle: PropTypes.func.isRequired,
onReport: PropTypes.func.isRequired,
onMute: PropTypes.func.isRequired,
onBlockDomain: PropTypes.func.isRequired,
onUnblockDomain: PropTypes.func.isRequired,
onEndorseToggle: PropTypes.func.isRequired,
onAddToList: PropTypes.func.isRequired,
onAddToAntenna: PropTypes.func.isRequired,
onAddToExcludeAntenna: PropTypes.func.isRequired,
onAddToCircle: PropTypes.func.isRequired,
onChangeLanguages: PropTypes.func.isRequired,
onInteractionModal: PropTypes.func.isRequired,
onOpenAvatar: PropTypes.func.isRequired,
onOpenURL: PropTypes.func.isRequired,
hideTabs: PropTypes.bool,
domain: PropTypes.string.isRequired,
hidden: PropTypes.bool,
};
handleFollow = () => {
this.props.onFollow(this.props.account);
};
handleBlock = () => {
this.props.onBlock(this.props.account);
};
handleMention = () => {
this.props.onMention(this.props.account);
};
handleDirect = () => {
this.props.onDirect(this.props.account);
};
handleReport = () => {
this.props.onReport(this.props.account);
};
handleReblogToggle = () => {
this.props.onReblogToggle(this.props.account);
};
handleNotifyToggle = () => {
this.props.onNotifyToggle(this.props.account);
};
handleMute = () => {
this.props.onMute(this.props.account);
};
handleBlockDomain = () => {
this.props.onBlockDomain(this.props.account);
};
handleUnblockDomain = () => {
const domain = this.props.account.get('acct').split('@')[1];
if (!domain) return;
this.props.onUnblockDomain(domain);
};
handleEndorseToggle = () => {
this.props.onEndorseToggle(this.props.account);
};
handleAddToList = () => {
this.props.onAddToList(this.props.account);
};
handleAddToAntenna = () => {
this.props.onAddToAntenna(this.props.account);
};
handleAddToExcludeAntenna = () => {
this.props.onAddToExcludeAntenna(this.props.account);
};
handleAddToCircle = () => {
this.props.onAddToCircle(this.props.account);
};
handleEditAccountNote = () => {
this.props.onEditAccountNote(this.props.account);
};
handleChangeLanguages = () => {
this.props.onChangeLanguages(this.props.account);
};
handleInteractionModal = () => {
this.props.onInteractionModal(this.props.account);
};
handleOpenAvatar = () => {
this.props.onOpenAvatar(this.props.account);
};
render () {
const { account, featuredTags, hidden, hideTabs } = this.props;
if (account === null) {
return null;
}
return (
<div className='account-timeline__header'>
{(!hidden && account.get('memorial')) && <MemorialNote />}
{(!hidden && account.get('moved')) && <MovedNote from={account} to={account.get('moved')} />}
<InnerHeader
account={account}
featuredTags={featuredTags}
onFollow={this.handleFollow}
onBlock={this.handleBlock}
onMention={this.handleMention}
onDirect={this.handleDirect}
onReblogToggle={this.handleReblogToggle}
onNotifyToggle={this.handleNotifyToggle}
onReport={this.handleReport}
onMute={this.handleMute}
onBlockDomain={this.handleBlockDomain}
onUnblockDomain={this.handleUnblockDomain}
onEndorseToggle={this.handleEndorseToggle}
onAddToList={this.handleAddToList}
onAddToAntenna={this.handleAddToAntenna}
onAddToExcludeAntenna={this.handleAddToExcludeAntenna}
onAddToCircle={this.handleAddToCircle}
onEditAccountNote={this.handleEditAccountNote}
onChangeLanguages={this.handleChangeLanguages}
onInteractionModal={this.handleInteractionModal}
onOpenAvatar={this.handleOpenAvatar}
onOpenURL={this.props.onOpenURL}
domain={this.props.domain}
hidden={hidden}
/>
{!(hideTabs || hidden) && (
<div className='account__section-headline'>
<NavLink exact to={`/@${account.get('acct')}`}><FormattedMessage id='account.posts' defaultMessage='Posts' /></NavLink>
<NavLink exact to={`/@${account.get('acct')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Posts and replies' /></NavLink>
<NavLink exact to={`/@${account.get('acct')}/media`}><FormattedMessage id='account.media' defaultMessage='Media' /></NavLink>
</div>
)}
</div>
);
}
}
export default Header;

View file

@ -1,183 +0,0 @@
import { injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { openURL } from 'mastodon/actions/search';
import {
followAccount,
unblockAccount,
unmuteAccount,
pinAccount,
unpinAccount,
} from '../../../actions/accounts';
import { initBlockModal } from '../../../actions/blocks';
import {
mentionCompose,
directCompose,
} from '../../../actions/compose';
import { initDomainBlockModal, unblockDomain } from '../../../actions/domain_blocks';
import { openModal } from '../../../actions/modal';
import { initMuteModal } from '../../../actions/mutes';
import { initReport } from '../../../actions/reports';
import { makeGetAccount, getAccountHidden } from '../../../selectors';
import Header from '../components/header';
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();
const mapStateToProps = (state, { accountId }) => ({
account: getAccount(state, accountId),
domain: state.getIn(['meta', 'domain']),
hidden: getAccountHidden(state, accountId),
featuredTags: state.getIn(['user_lists', 'featured_tags', accountId, 'items']),
});
return mapStateToProps;
};
const mapDispatchToProps = (dispatch) => ({
onFollow (account) {
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
dispatch(openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }));
} else {
dispatch(followAccount(account.get('id')));
}
},
onInteractionModal (account) {
dispatch(openModal({
modalType: 'INTERACTION',
modalProps: {
type: 'follow',
accountId: account.get('id'),
url: account.get('uri'),
},
}));
},
onBlock (account) {
if (account.getIn(['relationship', 'blocking'])) {
dispatch(unblockAccount(account.get('id')));
} else {
dispatch(initBlockModal(account));
}
},
onMention (account) {
dispatch(mentionCompose(account));
},
onDirect (account) {
dispatch(directCompose(account));
},
onReblogToggle (account) {
if (account.getIn(['relationship', 'showing_reblogs'])) {
dispatch(followAccount(account.get('id'), { reblogs: false }));
} else {
dispatch(followAccount(account.get('id'), { reblogs: true }));
}
},
onEndorseToggle (account) {
if (account.getIn(['relationship', 'endorsed'])) {
dispatch(unpinAccount(account.get('id')));
} else {
dispatch(pinAccount(account.get('id')));
}
},
onNotifyToggle (account) {
if (account.getIn(['relationship', 'notifying'])) {
dispatch(followAccount(account.get('id'), { notify: false }));
} else {
dispatch(followAccount(account.get('id'), { notify: true }));
}
},
onReport (account) {
dispatch(initReport(account));
},
onMute (account) {
if (account.getIn(['relationship', 'muting'])) {
dispatch(unmuteAccount(account.get('id')));
} else {
dispatch(initMuteModal(account));
}
},
onBlockDomain (account) {
dispatch(initDomainBlockModal(account));
},
onUnblockDomain (domain) {
dispatch(unblockDomain(domain));
},
onAddToList (account) {
dispatch(openModal({
modalType: 'LIST_ADDER',
modalProps: {
accountId: account.get('id'),
},
}));
},
onAddToAntenna (account) {
dispatch(openModal({
modalType: 'ANTENNA_ADDER',
modalProps: {
accountId: account.get('id'),
isExclude: false,
},
}));
},
onAddToExcludeAntenna (account) {
dispatch(openModal({
modalType: 'ANTENNA_ADDER',
modalProps: {
accountId: account.get('id'),
isExclude: true,
},
}));
},
onAddToCircle (account) {
dispatch(openModal({
modalType: 'CIRCLE_ADDER',
modalProps: {
accountId: account.get('id'),
},
}));
},
onChangeLanguages (account) {
dispatch(openModal({
modalType: 'SUBSCRIBED_LANGUAGES',
modalProps: {
accountId: account.get('id'),
},
}));
},
onOpenAvatar (account) {
dispatch(openModal({
modalType: 'IMAGE',
modalProps: {
src: account.get('avatar'),
alt: '',
},
}));
},
onOpenURL (url) {
return dispatch(openURL({ url }));
},
});
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header));

View file

@ -11,7 +11,7 @@ import { TimelineHint } from 'mastodon/components/timeline_hint';
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
import { me } from 'mastodon/initial_state';
import { normalizeForLookup } from 'mastodon/reducers/accounts_map';
import { getAccountHidden } from 'mastodon/selectors';
import { getAccountHidden } from 'mastodon/selectors/accounts';
import { useAppSelector } from 'mastodon/store';
import { lookupAccount, fetchAccount } from '../../actions/accounts';
@ -22,8 +22,8 @@ import { LoadingIndicator } from '../../components/loading_indicator';
import StatusList from '../../components/status_list';
import Column from '../ui/components/column';
import { AccountHeader } from './components/account_header';
import { LimitedAccountHint } from './components/limited_account_hint';
import HeaderContainer from './containers/header_container';
const emptyList = ImmutableList();
@ -198,7 +198,7 @@ class AccountTimeline extends ImmutablePureComponent {
<ColumnBackButton />
<StatusList
prepend={<HeaderContainer accountId={this.props.accountId} hideTabs={forceEmptyState} tagged={this.props.params.tagged} />}
prepend={<AccountHeader accountId={this.props.accountId} hideTabs={forceEmptyState} tagged={this.props.params.tagged} />}
alwaysPrepend
append={remoteMessage}
scrollKey='account_timeline'