Merge branch 'account-fqn' into 'develop'

Make FQN for local accounts configurable

See merge request soapbox-pub/soapbox-fe!471
merge-requests/472/head
Alex Gleason 2021-04-10 21:34:05 +00:00
commit 0b87296c15
11 zmienionych plików z 83 dodań i 26 usunięć

Wyświetl plik

@ -24,6 +24,8 @@ const allowedEmojiRGI = ImmutableList([
'😩',
]);
const year = new Date().getFullYear();
export const defaultConfig = ImmutableMap({
logo: '',
banner: '',
@ -34,12 +36,13 @@ export const defaultConfig = ImmutableMap({
}),
extensions: ImmutableMap(),
defaultSettings: ImmutableMap(),
copyright: '♥2020. Copying is an act of love. Please copy and share.',
copyright: `${year}. Copying is an act of love. Please copy and share.`,
navlinks: ImmutableMap({
homeFooter: ImmutableList(),
}),
allowedEmoji: allowedEmoji,
verifiedCanEditName: false,
displayFqn: true,
});
export function getSoapboxConfig(state) {

Wyświetl plik

@ -1,21 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import VerificationBadge from './verification_badge';
import { acctFull } from '../utils/accounts';
import { getAcct } from '../utils/accounts';
import { List as ImmutableList } from 'immutable';
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
import { displayFqn } from 'soapbox/utils/state';
export default class DisplayName extends React.PureComponent {
const mapStateToProps = state => {
return {
displayFqn: displayFqn(state),
};
};
export default @connect(mapStateToProps)
class DisplayName extends React.PureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
displayFqn: PropTypes.bool,
others: ImmutablePropTypes.list,
children: PropTypes.node,
};
render() {
const { account, others, children } = this.props;
const { account, displayFqn, others, children } = this.props;
let displayName, suffix;
const verified = account.getIn(['pleroma', 'tags'], ImmutableList()).includes('verified');
@ -38,7 +48,7 @@ export default class DisplayName extends React.PureComponent {
{verified && <VerificationBadge />}
</>
);
suffix = <span className='display-name__account'>@{acctFull(account)}</span>;
suffix = <span className='display-name__account'>@{getAcct(account, displayFqn)}</span>;
}
return (

Wyświetl plik

@ -6,13 +6,14 @@ import { injectIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Avatar from 'soapbox/components/avatar';
import { acctFull } from 'soapbox/utils/accounts';
import { getAcct } from 'soapbox/utils/accounts';
import { fetchChat, markChatRead } from 'soapbox/actions/chats';
import ChatBox from './components/chat_box';
import Column from 'soapbox/components/column';
import ColumnBackButton from 'soapbox/components/column_back_button';
import { Map as ImmutableMap } from 'immutable';
import { makeGetChat } from 'soapbox/selectors';
import { displayFqn } from 'soapbox/utils/state';
const mapStateToProps = (state, { params }) => {
const getChat = makeGetChat();
@ -21,6 +22,7 @@ const mapStateToProps = (state, { params }) => {
return {
me: state.get('me'),
chat: getChat(state, chat),
displayFqn: displayFqn(state),
};
};
@ -32,6 +34,7 @@ class ChatRoom extends ImmutablePureComponent {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
chat: ImmutablePropTypes.map,
displayFqn: PropTypes.bool,
me: PropTypes.node,
}
@ -68,7 +71,7 @@ class ChatRoom extends ImmutablePureComponent {
}
render() {
const { chat } = this.props;
const { chat, displayFqn } = this.props;
if (!chat) return null;
const account = chat.get('account');
@ -79,7 +82,7 @@ class ChatRoom extends ImmutablePureComponent {
<Link to={`/@${account.get('acct')}`} className='chatroom__header'>
<Avatar account={account} size={18} />
<div className='chatroom__title'>
@{acctFull(account)}
@{getAcct(account, displayFqn)}
</div>
</Link>
</div>

Wyświetl plik

@ -6,7 +6,7 @@ import { injectIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Avatar from 'soapbox/components/avatar';
import { acctFull } from 'soapbox/utils/accounts';
import { getAcct } from 'soapbox/utils/accounts';
import IconButton from 'soapbox/components/icon_button';
import {
closeChat,
@ -14,11 +14,13 @@ import {
} from 'soapbox/actions/chats';
import ChatBox from './chat_box';
import { shortNumberFormat } from 'soapbox/utils/numbers';
import { displayFqn } from 'soapbox/utils/state';
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
const mapStateToProps = (state, { pane }) => ({
me: state.get('me'),
chat: state.getIn(['chats', pane.get('chat_id')]),
displayFqn: displayFqn(state),
});
export default @connect(mapStateToProps)
@ -32,6 +34,7 @@ class ChatWindow extends ImmutablePureComponent {
idx: PropTypes.number,
chat: ImmutablePropTypes.map,
me: PropTypes.node,
displayFqn: PropTypes.bool,
}
state = {
@ -73,7 +76,7 @@ class ChatWindow extends ImmutablePureComponent {
}
render() {
const { pane, idx, chat } = this.props;
const { pane, idx, chat, displayFqn } = this.props;
const account = pane.getIn(['chat', 'account']);
if (!chat || !account) return null;
@ -99,7 +102,7 @@ class ChatWindow extends ImmutablePureComponent {
<div className='pane__header'>
{unreadCount > 0 ? unreadIcon : avatar }
<button className='pane__title' onClick={this.handleChatToggle(chat.get('id'))}>
@{acctFull(account)}
@{getAcct(account, displayFqn)}
</button>
<div className='pane__close'>
<IconButton icon='close' title='Close chat' onClick={this.handleChatClose(chat.get('id'))} />

Wyświetl plik

@ -1,11 +1,18 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { acctFull } from 'soapbox/utils/accounts';
import { getAcct } from 'soapbox/utils/accounts';
import StillImage from 'soapbox/components/still_image';
import VerificationBadge from 'soapbox/components/verification_badge';
import { List as ImmutableList } from 'immutable';
import { displayFqn } from 'soapbox/utils/state';
const ProfilePreview = ({ account }) => (
const mapStateToProps = state => ({
displayFqn: displayFqn(state),
});
const ProfilePreview = ({ account, displayFqn }) => (
<div className='card h-card'>
<a target='_blank' rel='noopener' href={account.get('url')}>
<div className='card__img'>
@ -23,7 +30,7 @@ const ProfilePreview = ({ account }) => (
{account.getIn(['pleroma', 'tags'], ImmutableList()).includes('verified') && <VerificationBadge />}
</strong>
</bdi>
<span>{acctFull(account)}</span>
<span>@{getAcct(account, displayFqn)}</span>
</div>
</div>
</a>
@ -32,6 +39,7 @@ const ProfilePreview = ({ account }) => (
ProfilePreview.propTypes = {
account: ImmutablePropTypes.map,
displayFqn: PropTypes.bool,
};
export default ProfilePreview;
export default connect(mapStateToProps)(ProfilePreview);

Wyświetl plik

@ -41,6 +41,7 @@ const messages = defineMessages({
rawJSONLabel: { id: 'soapbox_config.raw_json_label', defaultMessage: 'Advanced: Edit raw JSON data' },
rawJSONHint: { id: 'soapbox_config.raw_json_hint', defaultMessage: 'Edit the settings data directly. Changes made directly to the JSON file will override the form fields above. Click "Save" to apply your changes.' },
verifiedCanEditNameLabel: { id: 'soapbox_config.verified_can_edit_name_label', defaultMessage: 'Allow verified users to edit their own display name.' },
displayFqnLabel: { id: 'soapbox_config.display_fqn_label', defaultMessage: 'Display domain even for local accounts.' },
});
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
@ -241,6 +242,12 @@ class SoapboxConfig extends ImmutablePureComponent {
checked={soapbox.get('verifiedCanEditName') === true}
onChange={this.handleChange(['verifiedCanEditName'], (e) => e.target.checked)}
/>
<Checkbox
name='verifiedCanEditName'
label={intl.formatMessage(messages.displayFqnLabel)}
checked={soapbox.get('displayFqn') === true}
onChange={this.handleChange(['displayFqn'], (e) => e.target.checked)}
/>
</FieldsGroup>
<FieldsGroup>
<div className='input with_block_label popup'>

Wyświetl plik

@ -10,7 +10,8 @@ import Icon from 'soapbox/components/icon';
import VerificationBadge from 'soapbox/components/verification_badge';
import Badge from 'soapbox/components/badge';
import { List as ImmutableList } from 'immutable';
import { acctFull, isAdmin, isModerator } from 'soapbox/utils/accounts';
import { getAcct, isAdmin, isModerator } from 'soapbox/utils/accounts';
import { displayFqn } from 'soapbox/utils/state';
import classNames from 'classnames';
const messages = defineMessages({
@ -36,10 +37,11 @@ class ProfileInfoPanel extends ImmutablePureComponent {
identity_proofs: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
username: PropTypes.string,
displayFqn: PropTypes.bool,
};
render() {
const { account, intl, identity_proofs, username } = this.props;
const { account, displayFqn, intl, identity_proofs, username } = this.props;
if (!account) {
return (
@ -73,7 +75,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
<span dangerouslySetInnerHTML={displayNameHtml} className='profile-info-panel__name-content' />
{verified && <VerificationBadge />}
{account.get('bot') && <Badge slug='bot' title={intl.formatMessage(messages.bot)} />}
{ <small>@{acctFull(account)} {lockedIcon}</small> }
{ <small>@{getAcct(account, displayFqn)} {lockedIcon}</small> }
</h1>
</div>
@ -144,6 +146,7 @@ const mapStateToProps = (state, { account }) => {
return {
identity_proofs,
domain: state.getIn(['meta', 'domain']),
displayFqn: displayFqn(state),
};
};

Wyświetl plik

@ -8,7 +8,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Avatar from 'soapbox/components/avatar';
import { shortNumberFormat } from 'soapbox/utils/numbers';
import { acctFull } from 'soapbox/utils/accounts';
import { getAcct } from 'soapbox/utils/accounts';
import { displayFqn } from 'soapbox/utils/state';
import StillImage from 'soapbox/components/still_image';
import VerificationBadge from 'soapbox/components/verification_badge';
import { List as ImmutableList } from 'immutable';
@ -17,12 +18,13 @@ class UserPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
displayFqn: PropTypes.bool,
intl: PropTypes.object.isRequired,
domain: PropTypes.string,
}
render() {
const { account, intl, domain } = this.props;
const { account, displayFqn, intl, domain } = this.props;
if (!account) return null;
const displayNameHtml = { __html: account.get('display_name_html') };
const acct = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
@ -49,7 +51,7 @@ class UserPanel extends ImmutablePureComponent {
<Link to={`/@${account.get('acct')}`}>
<span className='user-panel__account__name' dangerouslySetInnerHTML={displayNameHtml} />
{verified && <VerificationBadge />}
<small className='user-panel__account__username'>@{acctFull(account)}</small>
<small className='user-panel__account__username'>@{getAcct(account, displayFqn)}</small>
</Link>
</h1>
</div>
@ -93,6 +95,7 @@ const makeMapStateToProps = () => {
const mapStateToProps = (state, { accountId }) => ({
account: getAccount(state, accountId),
displayFqn: displayFqn(state),
});
return mapStateToProps;

Wyświetl plik

@ -10,7 +10,8 @@ import LinkFooter from '../features/ui/components/link_footer';
import SignUpPanel from '../features/ui/components/sign_up_panel';
import ProfileInfoPanel from '../features/ui/components/profile_info_panel';
import ProfileMediaPanel from '../features/ui/components/profile_media_panel';
import { acctFull } from 'soapbox/utils/accounts';
import { getAcct } from 'soapbox/utils/accounts';
import { displayFqn } from 'soapbox/utils/state';
import { getFeatures } from 'soapbox/utils/features';
import { makeGetAccount } from '../selectors';
import { Redirect } from 'react-router-dom';
@ -47,6 +48,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
accountUsername,
features: getFeatures(state.get('instance')),
realAccount,
displayFqn: displayFqn(state),
};
};
@ -56,11 +58,12 @@ class ProfilePage extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
accountUsername: PropTypes.string.isRequired,
displayFqn: PropTypes.bool,
features: PropTypes.object,
};
render() {
const { children, accountId, account, accountUsername, features, realAccount } = this.props;
const { children, accountId, account, displayFqn, accountUsername, features, realAccount } = this.props;
const bg = account ? account.getIn(['customizations', 'background']) : undefined;
if (realAccount) {
@ -70,7 +73,7 @@ class ProfilePage extends ImmutablePureComponent {
return (
<div className={bg && `page page--customization page--${bg}` || 'page'}>
{account && <Helmet>
<title>@{acctFull(account)}</title>
<title>@{getAcct(account, displayFqn)}</title>
</Helmet>}
<div className='page__top'>

Wyświetl plik

@ -16,13 +16,21 @@ export const getDomain = account => {
return domain;
};
// user@domain even for local users
export const acctFull = account => {
export const guessFqn = account => {
const [user, domain] = account.get('acct').split('@');
if (!domain) return [user, guessDomain(account)].join('@');
return account.get('acct');
};
// user@domain even for local users
export const acctFull = account => (
account.get('fqn') || guessFqn(account)
);
export const getAcct = (account, displayFqn) => (
displayFqn === true ? acctFull(account) : account.get('acct')
);
export const isStaff = (account = ImmutableMap()) => (
[isAdmin, isModerator].some(f => f(account) === true)
);

Wyświetl plik

@ -0,0 +1,6 @@
import { getSoapboxConfig } from'soapbox/actions/soapbox';
export const displayFqn = state => {
const soapbox = getSoapboxConfig(state);
return soapbox.get('displayFqn');
};