Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: - package.json Not really a conflict, caused by an additional dependency in glitch-soc. - yarn.lock Not really a conflict, caused by an additional dependency in glitch-soc.
This commit is contained in:
@@ -238,9 +238,18 @@ class Header extends ImmutablePureComponent {
|
||||
const content = { __html: account.get('note_emojified') };
|
||||
const displayNameHtml = { __html: account.get('display_name_html') };
|
||||
const fields = account.get('fields');
|
||||
const badge = account.get('bot') ? (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>) : null;
|
||||
const acct = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
|
||||
|
||||
let badge;
|
||||
|
||||
if (account.get('bot')) {
|
||||
badge = (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>);
|
||||
} else if (account.get('group')) {
|
||||
badge = (<div className='account-role group'><FormattedMessage id='account.badges.group' defaultMessage='Group' /></div>);
|
||||
} else {
|
||||
badge = null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames('account__header', { inactive: !!account.get('moved') })} ref={this.setRef}>
|
||||
<div className='account__header__image'>
|
||||
|
@@ -13,6 +13,8 @@ const messages = defineMessages({
|
||||
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
|
||||
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
|
||||
poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
|
||||
switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple choices' },
|
||||
switchToSingle: { id: 'compose_form.poll.switch_to_single', defaultMessage: 'Change poll to allow for a single choice' },
|
||||
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
|
||||
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
|
||||
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
|
||||
@@ -50,6 +52,12 @@ class Option extends React.PureComponent {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
handleCheckboxKeypress = e => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
this.handleToggleMultiple(e);
|
||||
}
|
||||
}
|
||||
|
||||
onSuggestionsClearRequested = () => {
|
||||
this.props.onClearSuggestions();
|
||||
}
|
||||
@@ -71,8 +79,11 @@ class Option extends React.PureComponent {
|
||||
<span
|
||||
className={classNames('poll__input', { checkbox: isPollMultiple })}
|
||||
onClick={this.handleToggleMultiple}
|
||||
onKeyPress={this.handleCheckboxKeypress}
|
||||
role='button'
|
||||
tabIndex='0'
|
||||
title={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)}
|
||||
aria-label={intl.formatMessage(isPollMultiple ? messages.switchToMultiple : messages.switchToSingle)}
|
||||
/>
|
||||
|
||||
<AutosuggestInput
|
||||
|
@@ -57,6 +57,17 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div role='group' aria-labelledby='notifications-follow-request'>
|
||||
<span id='notifications-follow-request' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow_request' defaultMessage='New follow requests:' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow_request']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'follow_request']} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow_request']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow_request']} onChange={onChange} label={soundStr} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div role='group' aria-labelledby='notifications-favourite'>
|
||||
<span id='notifications-favourite' className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span>
|
||||
|
||||
|
@@ -0,0 +1,59 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import Avatar from 'mastodon/components/avatar';
|
||||
import DisplayName from 'mastodon/components/display_name';
|
||||
import Permalink from 'mastodon/components/permalink';
|
||||
import IconButton from 'mastodon/components/icon_button';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
const messages = defineMessages({
|
||||
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
|
||||
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
|
||||
});
|
||||
|
||||
export default @injectIntl
|
||||
class FollowRequest extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.map.isRequired,
|
||||
onAuthorize: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
render () {
|
||||
const { intl, hidden, account, onAuthorize, onReject } = this.props;
|
||||
|
||||
if (!account) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
if (hidden) {
|
||||
return (
|
||||
<Fragment>
|
||||
{account.get('display_name')}
|
||||
{account.get('username')}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='account'>
|
||||
<div className='account__wrapper'>
|
||||
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/accounts/${account.get('id')}`}>
|
||||
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
||||
<DisplayName account={account} />
|
||||
</Permalink>
|
||||
|
||||
<div className='account__relationship'>
|
||||
<IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} />
|
||||
<IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -7,6 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
import StatusContainer from 'mastodon/containers/status_container';
|
||||
import AccountContainer from 'mastodon/containers/account_container';
|
||||
import FollowRequestContainer from '../containers/follow_request_container';
|
||||
import Icon from 'mastodon/components/icon';
|
||||
import Permalink from 'mastodon/components/permalink';
|
||||
|
||||
@@ -127,7 +128,29 @@ class Notification extends ImmutablePureComponent {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<AccountContainer id={account.get('id')} withNote={false} hidden={this.props.hidden} />
|
||||
<AccountContainer id={account.get('id')} hidden={this.props.hidden} />
|
||||
</div>
|
||||
</HotKeys>
|
||||
);
|
||||
}
|
||||
|
||||
renderFollowRequest (notification, account, link) {
|
||||
const { intl } = this.props;
|
||||
|
||||
return (
|
||||
<HotKeys handlers={this.getHandlers()}>
|
||||
<div className='notification notification-follow-request focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.follow_request', defaultMessage: '{name} has requested to follow you' }, { name: account.get('acct') }), notification.get('created_at'))}>
|
||||
<div className='notification__message'>
|
||||
<div className='notification__favourite-icon-wrapper'>
|
||||
<Icon id='user' fixedWidth />
|
||||
</div>
|
||||
|
||||
<span title={notification.get('created_at')}>
|
||||
<FormattedMessage id='notification.follow_request' defaultMessage='{name} has requested to follow you' values={{ name: link }} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<FollowRequestContainer id={account.get('id')} withNote={false} hidden={this.props.hidden} />
|
||||
</div>
|
||||
</HotKeys>
|
||||
);
|
||||
@@ -261,6 +284,8 @@ class Notification extends ImmutablePureComponent {
|
||||
switch(notification.get('type')) {
|
||||
case 'follow':
|
||||
return this.renderFollow(notification, account, link);
|
||||
case 'follow_request':
|
||||
return this.renderFollowRequest(notification, account, link);
|
||||
case 'mention':
|
||||
return this.renderMention(notification);
|
||||
case 'favourite':
|
||||
|
@@ -0,0 +1,26 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { makeGetAccount } from 'mastodon/selectors';
|
||||
import FollowRequest from '../components/follow_request';
|
||||
import { authorizeFollowRequest, rejectFollowRequest } from 'mastodon/actions/accounts';
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getAccount = makeGetAccount();
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
account: getAccount(state, props.id),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch, { id }) => ({
|
||||
onAuthorize () {
|
||||
dispatch(authorizeFollowRequest(id));
|
||||
},
|
||||
|
||||
onReject () {
|
||||
dispatch(rejectFollowRequest(id));
|
||||
},
|
||||
});
|
||||
|
||||
export default connect(makeMapStateToProps, mapDispatchToProps)(FollowRequest);
|
@@ -120,9 +120,9 @@ class ActionBar extends React.PureComponent {
|
||||
const account = status.get('account');
|
||||
|
||||
if (relationship && relationship.get('blocking')) {
|
||||
onBlock(status);
|
||||
} else {
|
||||
onUnblock(account);
|
||||
} else {
|
||||
onBlock(status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -282,7 +282,7 @@ class Status extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
handleHotkeyOpenMedia = e => {
|
||||
const { status } = this.props;
|
||||
const status = this._properStatus();
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
|
@@ -4,12 +4,10 @@ import { fetchFollowRequests } from 'mastodon/actions/accounts';
|
||||
import { connect } from 'react-redux';
|
||||
import { NavLink, withRouter } from 'react-router-dom';
|
||||
import IconWithBadge from 'mastodon/components/icon_with_badge';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
locked: state.getIn(['accounts', me, 'locked']),
|
||||
count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
|
||||
});
|
||||
|
||||
@@ -19,22 +17,19 @@ class FollowRequestsNavLink extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
locked: PropTypes.bool,
|
||||
count: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch, locked } = this.props;
|
||||
const { dispatch } = this.props;
|
||||
|
||||
if (locked) {
|
||||
dispatch(fetchFollowRequests());
|
||||
}
|
||||
dispatch(fetchFollowRequests());
|
||||
}
|
||||
|
||||
render () {
|
||||
const { locked, count } = this.props;
|
||||
const { count } = this.props;
|
||||
|
||||
if (!locked || count === 0) {
|
||||
if (count === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user