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

This commit is contained in:
KMY 2023-10-21 10:32:06 +09:00
commit f9eaaec4e7
95 changed files with 1002 additions and 657 deletions

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
@ -12,6 +13,7 @@ import { changeBoostPrivacy } from 'mastodon/actions/boosts';
import AttachmentList from 'mastodon/components/attachment_list';
import { Icon } from 'mastodon/components/icon';
import PrivacyDropdown from 'mastodon/features/compose/components/privacy_dropdown';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { Avatar } from '../../../components/avatar';
import Button from '../../../components/button';
@ -49,11 +51,6 @@ const mapDispatchToProps = dispatch => {
};
class BoostModal extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
onReblog: PropTypes.func.isRequired,
@ -61,6 +58,7 @@ class BoostModal extends ImmutablePureComponent {
onChangeBoostPrivacy: PropTypes.func.isRequired,
privacy: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
...WithRouterPropTypes,
};
componentDidMount() {
@ -76,7 +74,7 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.props.onClose();
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
};
@ -155,4 +153,4 @@ class BoostModal extends ImmutablePureComponent {
}
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal));
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal)));

View file

@ -54,11 +54,6 @@ const componentMap = {
};
export default class ColumnsArea extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
};
static propTypes = {
columns: ImmutablePropTypes.list.isRequired,
isModalOpen: PropTypes.bool.isRequired,

View file

@ -100,7 +100,7 @@ class LinkFooter extends PureComponent {
{DividingCircle}
<a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='footer.source_code' defaultMessage='View source code' /></a>
{DividingCircle}
<span class='version'>v{version}</span>
<span className='version'>v{version}</span>
</p>
</div>
);

View file

@ -1,7 +1,5 @@
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
@ -71,4 +69,4 @@ class ListPanel extends ImmutablePureComponent {
}
export default withRouter(connect(mapStateToProps)(ListPanel));
export default connect(mapStateToProps)(ListPanel);

View file

@ -6,7 +6,7 @@ import { defineMessages, injectIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { WordmarkLogo } from 'mastodon/components/logo';
import NavigationPortal from 'mastodon/components/navigation_portal';
import { NavigationPortal } from 'mastodon/components/navigation_portal';
import { enableDtlMenu, timelinePreview, trendsEnabled, dtlTag } from 'mastodon/initial_state';
import { transientSingleColumn } from 'mastodon/is_mobile';
@ -41,7 +41,6 @@ const messages = defineMessages({
class NavigationPanel extends Component {
static contextTypes = {
router: PropTypes.object.isRequired,
identity: PropTypes.object.isRequired,
};
@ -66,25 +65,31 @@ class NavigationPanel extends Component {
) : (
<ColumnLink transparent to='/search' icon='search' text={intl.formatMessage(messages.search)} />
));
let banner = undefined;
if(transientSingleColumn)
banner = (<div className='switch-to-advanced'>
{intl.formatMessage(messages.openedInClassicInterface)}
{" "}
<a href={`/deck${location.pathname}`} className='switch-to-advanced__toggle'>
{intl.formatMessage(messages.advancedInterface)}
</a>
</div>);
return (
<div className='navigation-panel'>
<div className='navigation-panel__logo'>
<Link to='/' className='column-link column-link--logo'><WordmarkLogo /></Link>
{transientSingleColumn ? (
<div class='switch-to-advanced'>
{intl.formatMessage(messages.openedInClassicInterface)}
{" "}
<a href={`/deck${location.pathname}`} class='switch-to-advanced__toggle'>
{intl.formatMessage(messages.advancedInterface)}
</a>
</div>
) : (
<hr />
)}
{!banner && <hr />}
</div>
{banner &&
<div class='navigation-panel__banner'>
{banner}
</div>
}
{signedIn && (
<>
<ColumnLink transparent to='/home' icon='home' text={intl.formatMessage(messages.home)} />

View file

@ -16,6 +16,7 @@ import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'mastodo
import { INTRODUCTION_VERSION } from 'mastodon/actions/onboarding';
import PictureInPicture from 'mastodon/features/picture_in_picture';
import { layoutFromWindow } from 'mastodon/is_mobile';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose';
import { clearHeight } from '../../actions/height_cache';
@ -278,7 +279,6 @@ class SwitchingColumnsArea extends PureComponent {
class UI extends PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
identity: PropTypes.object.isRequired,
};
@ -289,12 +289,12 @@ class UI extends PureComponent {
hasComposingText: PropTypes.bool,
hasMediaAttachments: PropTypes.bool,
canUploadMore: PropTypes.bool,
location: PropTypes.object,
intl: PropTypes.object.isRequired,
dropdownMenuIsOpen: PropTypes.bool,
layout: PropTypes.string.isRequired,
firstLaunch: PropTypes.bool,
username: PropTypes.string,
...WithRouterPropTypes,
};
state = {
@ -391,7 +391,7 @@ class UI extends PureComponent {
handleServiceWorkerPostMessage = ({ data }) => {
if (data.type === 'navigate') {
this.context.router.history.push(data.path);
this.props.history.push(data.path);
} else {
console.warn('Unknown message type:', data.type);
}
@ -512,12 +512,12 @@ class UI extends PureComponent {
};
handleHotkeyBack = () => {
const { router } = this.context;
const { history } = this.props;
if (router.history.location?.state?.fromMastodon) {
router.history.goBack();
if (history.location?.state?.fromMastodon) {
history.goBack();
} else {
router.history.push('/');
history.push('/');
}
};
@ -527,38 +527,38 @@ class UI extends PureComponent {
handleHotkeyToggleHelp = () => {
if (this.props.location.pathname === '/keyboard-shortcuts') {
this.context.router.history.goBack();
this.props.history.goBack();
} else {
this.context.router.history.push('/keyboard-shortcuts');
this.props.history.push('/keyboard-shortcuts');
}
};
handleHotkeyGoToHome = () => {
this.context.router.history.push('/home');
this.props.history.push('/home');
};
handleHotkeyGoToNotifications = () => {
this.context.router.history.push('/notifications');
this.props.history.push('/notifications');
};
handleHotkeyGoToLocal = () => {
this.context.router.history.push('/public/local');
this.props.history.push('/public/local');
};
handleHotkeyGoToFederated = () => {
this.context.router.history.push('/public');
this.props.history.push('/public');
};
handleHotkeyGoToDirect = () => {
this.context.router.history.push('/conversations');
this.props.history.push('/conversations');
};
handleHotkeyGoToStart = () => {
this.context.router.history.push('/getting-started');
this.props.history.push('/getting-started');
};
handleHotkeyGoToFavourites = () => {
this.context.router.history.push('/favourites');
this.props.history.push('/favourites');
};
handleHotkeyGoToEmojiReactions = () => {
@ -566,23 +566,23 @@ class UI extends PureComponent {
};
handleHotkeyGoToPinned = () => {
this.context.router.history.push('/pinned');
this.props.history.push('/pinned');
};
handleHotkeyGoToProfile = () => {
this.context.router.history.push(`/@${this.props.username}`);
this.props.history.push(`/@${this.props.username}`);
};
handleHotkeyGoToBlocked = () => {
this.context.router.history.push('/blocks');
this.props.history.push('/blocks');
};
handleHotkeyGoToMuted = () => {
this.context.router.history.push('/mutes');
this.props.history.push('/mutes');
};
handleHotkeyGoToRequests = () => {
this.context.router.history.push('/follow_requests');
this.props.history.push('/follow_requests');
};
render () {

View file

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import { Component, PureComponent, cloneElement, Children } from 'react';
import { Component, cloneElement, Children } from 'react';
import { Switch, Route } from 'react-router-dom';
import { Switch, Route, useLocation } from 'react-router-dom';
import StackTrace from 'stacktrace-js';
@ -10,27 +10,20 @@ import ColumnLoading from '../components/column_loading';
import BundleContainer from '../containers/bundle_container';
// Small wrapper to pass multiColumn to the route components
export class WrappedSwitch extends PureComponent {
static contextTypes = {
router: PropTypes.object,
};
export const WrappedSwitch = ({ multiColumn, children }) => {
const location = useLocation();
render () {
const { multiColumn, children } = this.props;
const { location } = this.context.router.route;
const decklessLocation = multiColumn && location.pathname.startsWith('/deck')
? {...location, pathname: location.pathname.slice(5)}
: location;
const decklessLocation = multiColumn && location.pathname.startsWith('/deck')
? {...location, pathname: location.pathname.slice(5)}
: location;
return (
<Switch location={decklessLocation}>
{Children.map(children, child => child ? cloneElement(child, { multiColumn }) : null)}
</Switch>
);
};
return (
<Switch location={decklessLocation}>
{Children.map(children, child => child ? cloneElement(child, { multiColumn }) : null)}
</Switch>
);
}
}
WrappedSwitch.propTypes = {
multiColumn: PropTypes.bool,