Merge pull request #404 from ThibG/glitch-soc/features/moved-note

[Untested] [Glitch] Profile redirect notes
main
David Yip 2018-03-29 09:26:31 -05:00 committed by GitHub
commit 1bd12cf8eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 4 deletions

View File

@ -99,7 +99,7 @@ export default class Account extends ImmutablePureComponent {
{hidingNotificationsButton} {hidingNotificationsButton}
</Fragment> </Fragment>
); );
} else if (!account.get('moved')) { } else if (!account.get('moved') || following) {
buttons = <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} active={following} />; buttons = <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} active={following} />;
} }
} }

View File

@ -10,6 +10,7 @@ import IconButton from 'flavours/glitch/components/icon_button';
import emojify from 'flavours/glitch/util/emoji'; import emojify from 'flavours/glitch/util/emoji';
import { me } from 'flavours/glitch/util/initial_state'; import { me } from 'flavours/glitch/util/initial_state';
import { processBio } from 'flavours/glitch/util/bio_metadata'; import { processBio } from 'flavours/glitch/util/bio_metadata';
import classNames from 'classnames';
const messages = defineMessages({ const messages = defineMessages({
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
@ -75,11 +76,15 @@ export default class Header extends ImmutablePureComponent {
} }
} }
if (account.get('moved') && !account.getIn(['relationship', 'following'])) {
actionBtn = '';
}
const { text, metadata } = processBio(account.get('note')); const { text, metadata } = processBio(account.get('note'));
return ( return (
<div className='account__header__wrapper'> <div className='account__header__wrapper'>
<div className='account__header' style={{ backgroundImage: `url(${account.get('header')})` }}> <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${account.get('header')})` }}>
<div> <div>
<a <a
href={account.get('url')} href={account.get('url')}

View File

@ -7,6 +7,7 @@ import MissingIndicator from 'flavours/glitch/components/missing_indicator';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import MovedNote from './moved_note';
export default class Header extends ImmutablePureComponent { export default class Header extends ImmutablePureComponent {
@ -76,6 +77,8 @@ export default class Header extends ImmutablePureComponent {
return ( return (
<div className='account-timeline__header'> <div className='account-timeline__header'>
{account.get('moved') && <MovedNote from={account} to={account.get('moved')} />}
<InnerHeader <InnerHeader
account={account} account={account}
onFollow={this.handleFollow} onFollow={this.handleFollow}

View File

@ -0,0 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import AvatarOverlay from '../../../components/avatar_overlay';
import DisplayName from '../../../components/display_name';
export default class MovedNote extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
};
static propTypes = {
from: ImmutablePropTypes.map.isRequired,
to: ImmutablePropTypes.map.isRequired,
};
handleAccountClick = e => {
if (e.button === 0) {
e.preventDefault();
this.context.router.history.push(`/accounts/${this.props.to.get('id')}`);
}
e.stopPropagation();
}
render () {
const { from, to } = this.props;
const displayNameHtml = { __html: from.get('display_name_html') };
return (
<div className='account__moved-note'>
<div className='account__moved-note__message'>
<div className='account__moved-note__icon-wrapper'><i className='fa fa-fw fa-suitcase account__moved-note__icon' /></div>
<FormattedMessage id='account.moved_to' defaultMessage='{name} has moved to:' values={{ name: <strong dangerouslySetInnerHTML={displayNameHtml} /> }} />
</div>
<a href={to.get('url')} onClick={this.handleAccountClick} className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'><AvatarOverlay account={to} friend={from} /></div>
<DisplayName account={to} />
</a>
</div>
);
}
}

View File

@ -63,6 +63,11 @@ const normalizeAccount = (state, account) => {
account.display_name_html = emojify(escapeTextContentForBrowser(displayName)); account.display_name_html = emojify(escapeTextContentForBrowser(displayName));
account.note_emojified = emojify(account.note); account.note_emojified = emojify(account.note);
if (account.moved) {
state = normalizeAccount(state, account.moved);
account.moved = account.moved.id;
}
return state.set(account.id, fromJS(account)); return state.set(account.id, fromJS(account));
}; };

View File

@ -4,14 +4,18 @@ import { List as ImmutableList } from 'immutable';
const getAccountBase = (state, id) => state.getIn(['accounts', id], null); const getAccountBase = (state, id) => state.getIn(['accounts', id], null);
const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null); const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null);
const getAccountRelationship = (state, id) => state.getIn(['relationships', id], null); const getAccountRelationship = (state, id) => state.getIn(['relationships', id], null);
const getAccountMoved = (state, id) => state.getIn(['accounts', state.getIn(['accounts', id, 'moved'])]);
export const makeGetAccount = () => { export const makeGetAccount = () => {
return createSelector([getAccountBase, getAccountCounters, getAccountRelationship], (base, counters, relationship) => { return createSelector([getAccountBase, getAccountCounters, getAccountRelationship, getAccountMoved], (base, counters, relationship, moved) => {
if (base === null) { if (base === null) {
return null; return null;
} }
return base.merge(counters).set('relationship', relationship); return base.merge(counters).withMutations(map => {
map.set('relationship', relationship);
map.set('moved', moved);
});
}); });
}; };