aboutsummaryrefslogtreecommitdiff
path: root/app/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/mastodon/actions/accounts.js32
-rw-r--r--app/javascript/mastodon/actions/compose.js4
-rw-r--r--app/javascript/mastodon/components/account.js2
-rw-r--r--app/javascript/mastodon/components/hashtag.js2
-rw-r--r--app/javascript/mastodon/components/status.js64
-rw-r--r--app/javascript/mastodon/components/status_action_bar.js2
-rw-r--r--app/javascript/mastodon/components/status_content.js6
-rw-r--r--app/javascript/mastodon/containers/mastodon.js6
-rw-r--r--app/javascript/mastodon/features/account/components/header.js6
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.js64
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/header.js6
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/moved_note.js2
-rw-r--r--app/javascript/mastodon/features/account_timeline/index.js55
-rw-r--r--app/javascript/mastodon/features/compose/components/navigation_bar.js4
-rw-r--r--app/javascript/mastodon/features/compose/components/reply_indicator.js2
-rw-r--r--app/javascript/mastodon/features/compose/index.js6
-rw-r--r--app/javascript/mastodon/features/direct_timeline/components/conversation.js2
-rw-r--r--app/javascript/mastodon/features/directory/components/account_card.js2
-rw-r--r--app/javascript/mastodon/features/follow_requests/components/account_authorize.js2
-rw-r--r--app/javascript/mastodon/features/followers/index.js66
-rw-r--r--app/javascript/mastodon/features/following/index.js66
-rw-r--r--app/javascript/mastodon/features/getting_started/components/announcements.js6
-rw-r--r--app/javascript/mastodon/features/getting_started/index.js14
-rw-r--r--app/javascript/mastodon/features/home_timeline/index.js2
-rw-r--r--app/javascript/mastodon/features/lists/index.js2
-rw-r--r--app/javascript/mastodon/features/notifications/components/follow_request.js2
-rw-r--r--app/javascript/mastodon/features/notifications/components/notification.js6
-rw-r--r--app/javascript/mastodon/features/picture_in_picture/components/footer.js2
-rw-r--r--app/javascript/mastodon/features/picture_in_picture/components/header.js2
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js6
-rw-r--r--app/javascript/mastodon/features/status/index.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/boost_modal.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/columns_area.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/compose_panel.js7
-rw-r--r--app/javascript/mastodon/features/ui/components/list_panel.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/media_modal.js7
-rw-r--r--app/javascript/mastodon/features/ui/components/navigation_panel.js10
-rw-r--r--app/javascript/mastodon/features/ui/components/tabs_bar.js6
-rw-r--r--app/javascript/mastodon/features/ui/index.js48
-rw-r--r--app/javascript/mastodon/main.js6
-rw-r--r--app/javascript/mastodon/reducers/accounts_map.js15
-rw-r--r--app/javascript/mastodon/reducers/index.js2
-rw-r--r--app/javascript/mastodon/service_worker/web_push_notifications.js2
43 files changed, 349 insertions, 205 deletions
diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js
index 58b636602..ce7bb6d5f 100644
--- a/app/javascript/mastodon/actions/accounts.js
+++ b/app/javascript/mastodon/actions/accounts.js
@@ -5,6 +5,10 @@ export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
export const ACCOUNT_FETCH_FAIL = 'ACCOUNT_FETCH_FAIL';
+export const ACCOUNT_LOOKUP_REQUEST = 'ACCOUNT_LOOKUP_REQUEST';
+export const ACCOUNT_LOOKUP_SUCCESS = 'ACCOUNT_LOOKUP_SUCCESS';
+export const ACCOUNT_LOOKUP_FAIL = 'ACCOUNT_LOOKUP_FAIL';
+
export const ACCOUNT_FOLLOW_REQUEST = 'ACCOUNT_FOLLOW_REQUEST';
export const ACCOUNT_FOLLOW_SUCCESS = 'ACCOUNT_FOLLOW_SUCCESS';
export const ACCOUNT_FOLLOW_FAIL = 'ACCOUNT_FOLLOW_FAIL';
@@ -87,6 +91,34 @@ export function fetchAccount(id) {
};
};
+export const lookupAccount = acct => (dispatch, getState) => {
+ dispatch(lookupAccountRequest(acct));
+
+ api(getState).get('/api/v1/accounts/lookup', { params: { acct } }).then(response => {
+ dispatch(fetchRelationships([response.data.id]));
+ dispatch(importFetchedAccount(response.data));
+ dispatch(lookupAccountSuccess());
+ }).catch(error => {
+ dispatch(lookupAccountFail(acct, error));
+ });
+};
+
+export const lookupAccountRequest = (acct) => ({
+ type: ACCOUNT_LOOKUP_REQUEST,
+ acct,
+});
+
+export const lookupAccountSuccess = () => ({
+ type: ACCOUNT_LOOKUP_SUCCESS,
+});
+
+export const lookupAccountFail = (acct, error) => ({
+ type: ACCOUNT_LOOKUP_FAIL,
+ acct,
+ error,
+ skipAlert: true,
+});
+
export function fetchAccountRequest(id) {
return {
type: ACCOUNT_FETCH_REQUEST,
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index 891403969..2b2f1787e 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -72,7 +72,7 @@ const COMPOSE_PANEL_BREAKPOINT = 600 + (285 * 1) + (10 * 1);
export const ensureComposeIsVisible = (getState, routerHistory) => {
if (!getState().getIn(['compose', 'mounted']) && window.innerWidth < COMPOSE_PANEL_BREAKPOINT) {
- routerHistory.push('/statuses/new');
+ routerHistory.push('/publish');
}
};
@@ -152,7 +152,7 @@ export function submitCompose(routerHistory) {
'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
},
}).then(function (response) {
- if (routerHistory && routerHistory.location.pathname === '/statuses/new' && window.history.state) {
+ if (routerHistory && routerHistory.location.pathname === '/publish' && window.history.state) {
routerHistory.goBack();
}
diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js
index 0e40ee1d6..733192305 100644
--- a/app/javascript/mastodon/components/account.js
+++ b/app/javascript/mastodon/components/account.js
@@ -116,7 +116,7 @@ class Account extends ImmutablePureComponent {
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')}`}>
+ <Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
{mute_expires_at}
<DisplayName account={account} />
diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js
index d766ca90d..c23a4674d 100644
--- a/app/javascript/mastodon/components/hashtag.js
+++ b/app/javascript/mastodon/components/hashtag.js
@@ -27,7 +27,7 @@ const Hashtag = ({ hashtag }) => (
<div className='trends__item__name'>
<Permalink
href={hashtag.get('url')}
- to={`/timelines/tag/${hashtag.get('name')}`}
+ to={`/tags/${hashtag.get('name')}`}
>
#<span>{hashtag.get('name')}</span>
</Permalink>
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 295e83f58..52672e02e 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -134,42 +134,28 @@ class Status extends ImmutablePureComponent {
this.setState({ showMedia: !this.state.showMedia });
}
- handleClick = () => {
- if (this.props.onClick) {
- this.props.onClick();
+ handleClick = e => {
+ if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
return;
}
- if (!this.context.router) {
- return;
+ if (e) {
+ e.preventDefault();
}
- const { status } = this.props;
- this.context.router.history.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`);
+ this.handleHotkeyOpen();
}
- handleExpandClick = (e) => {
- if (this.props.onClick) {
- this.props.onClick();
+ handleAccountClick = e => {
+ if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
return;
}
- if (e.button === 0) {
- if (!this.context.router) {
- return;
- }
-
- const { status } = this.props;
- this.context.router.history.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`);
- }
- }
-
- handleAccountClick = (e) => {
- if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
- const id = e.currentTarget.getAttribute('data-id');
+ if (e) {
e.preventDefault();
- this.context.router.history.push(`/accounts/${id}`);
}
+
+ this.handleHotkeyOpenProfile();
}
handleExpandedToggle = () => {
@@ -242,11 +228,30 @@ class Status extends ImmutablePureComponent {
}
handleHotkeyOpen = () => {
- this.context.router.history.push(`/statuses/${this._properStatus().get('id')}`);
+ if (this.props.onClick) {
+ this.props.onClick();
+ return;
+ }
+
+ const { router } = this.context;
+ const status = this._properStatus();
+
+ if (!router) {
+ return;
+ }
+
+ router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
}
handleHotkeyOpenProfile = () => {
- this.context.router.history.push(`/accounts/${this._properStatus().getIn(['account', 'id'])}`);
+ const { router } = this.context;
+ const status = this._properStatus();
+
+ if (!router) {
+ return;
+ }
+
+ router.history.push(`/@${status.getIn(['account', 'acct'])}`);
}
handleHotkeyMoveUp = e => {
@@ -465,14 +470,15 @@ class Status extends ImmutablePureComponent {
{prepend}
<div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted })} data-id={status.get('id')}>
- <div className='status__expand' onClick={this.handleExpandClick} role='presentation' />
+ <div className='status__expand' onClick={this.handleClick} role='presentation' />
+
<div className='status__info'>
- <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
+ <a onClick={this.handleClick} href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
<span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
<RelativeTimestamp timestamp={status.get('created_at')} />
</a>
- <a onClick={this.handleAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'>
+ <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'>
<div className='status__avatar'>
{statusAvatar}
</div>
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 9981f2449..85c76edee 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -186,7 +186,7 @@ class StatusActionBar extends ImmutablePureComponent {
}
handleOpen = () => {
- this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/${this.props.status.get('id')}`);
}
handleEmbed = () => {
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index 35bd50514..b3d794280 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -112,7 +112,7 @@ export default class StatusContent extends React.PureComponent {
onMentionClick = (mention, e) => {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
- this.context.router.history.push(`/accounts/${mention.get('id')}`);
+ this.context.router.history.push(`/@${mention.get('acct')}`);
}
}
@@ -121,7 +121,7 @@ export default class StatusContent extends React.PureComponent {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
- this.context.router.history.push(`/timelines/tag/${hashtag}`);
+ this.context.router.history.push(`/tags/${hashtag}`);
}
}
@@ -202,7 +202,7 @@ export default class StatusContent extends React.PureComponent {
let mentionsPlaceholder = '';
const mentionLinks = status.get('mentions').map(item => (
- <Permalink to={`/accounts/${item.get('id')}`} href={item.get('url')} key={item.get('id')} className='mention'>
+ <Permalink to={`/@${item.get('acct')}`} href={item.get('url')} key={item.get('id')} className='mention'>
@<span>{item.get('username')}</span>
</Permalink>
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index 3ac58cf7c..3dcbe7923 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -14,7 +14,7 @@ import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from '../locales';
import { previewState as previewMediaState } from 'mastodon/features/ui/components/media_modal';
import { previewState as previewVideoState } from 'mastodon/features/ui/components/video_modal';
-import initialState from '../initial_state';
+import initialState, { me } from '../initial_state';
import ErrorBoundary from '../components/error_boundary';
const { localeData, messages } = getLocale();
@@ -27,7 +27,7 @@ store.dispatch(hydrateAction);
store.dispatch(fetchCustomEmojis());
const mapStateToProps = state => ({
- showIntroduction: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
+ showIntroduction: me && state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
});
@connect(mapStateToProps)
@@ -49,7 +49,7 @@ class MastodonMount extends React.PureComponent {
}
return (
- <BrowserRouter basename='/web'>
+ <BrowserRouter>
<ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}>
<Route path='/' component={UI} />
</ScrollContext>
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 8e49486bd..cf21a8d13 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -330,21 +330,21 @@ class Header extends ImmutablePureComponent {
{!suspended && (
<div className='account__header__extra__links'>
- <NavLink isActive={this.isStatusesPageActive} activeClassName='active' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}>
+ <NavLink isActive={this.isStatusesPageActive} activeClassName='active' to={`/@${account.get('acct')}`} title={intl.formatNumber(account.get('statuses_count'))}>
<ShortNumber
value={account.get('statuses_count')}
renderer={counterRenderer('statuses')}
/>
</NavLink>
- <NavLink exact activeClassName='active' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}>
+ <NavLink exact activeClassName='active' to={`/@${account.get('acct')}/following`} title={intl.formatNumber(account.get('following_count'))}>
<ShortNumber
value={account.get('following_count')}
renderer={counterRenderer('following')}
/>
</NavLink>
- <NavLink exact activeClassName='active' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
+ <NavLink exact activeClassName='active' to={`/@${account.get('acct')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
<ShortNumber
value={account.get('followers_count')}
renderer={counterRenderer('followers')}
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 015a6a6d7..477641098 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -2,7 +2,7 @@ import React from 'react';
import { connect } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
-import { fetchAccount } from 'mastodon/actions/accounts';
+import { lookupAccount } from 'mastodon/actions/accounts';
import { expandAccountMediaTimeline } from '../../actions/timelines';
import LoadingIndicator from 'mastodon/components/loading_indicator';
import Column from '../ui/components/column';
@@ -17,14 +17,25 @@ import MissingIndicator from 'mastodon/components/missing_indicator';
import { openModal } from 'mastodon/actions/modal';
import { FormattedMessage } from 'react-intl';
-const mapStateToProps = (state, props) => ({
- isAccount: !!state.getIn(['accounts', props.params.accountId]),
- attachments: getAccountGallery(state, props.params.accountId),
- isLoading: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'isLoading']),
- hasMore: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']),
- suspended: state.getIn(['accounts', props.params.accountId, 'suspended'], false),
- blockedBy: state.getIn(['relationships', props.params.accountId, 'blocked_by'], false),
-});
+const mapStateToProps = (state, { params: { acct } }) => {
+ const accountId = state.getIn(['accounts_map', acct]);
+
+ if (!accountId) {
+ return {
+ isLoading: true,
+ };
+ }
+
+ return {
+ accountId,
+ isAccount: !!state.getIn(['accounts', accountId]),
+ attachments: getAccountGallery(state, accountId),
+ isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading']),
+ hasMore: state.getIn(['timelines', `account:${accountId}:media`, 'hasMore']),
+ suspended: state.getIn(['accounts', accountId, 'suspended'], false),
+ blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false),
+ };
+};
class LoadMoreMedia extends ImmutablePureComponent {
@@ -53,7 +64,10 @@ export default @connect(mapStateToProps)
class AccountGallery extends ImmutablePureComponent {
static propTypes = {
- params: PropTypes.object.isRequired,
+ params: PropTypes.shape({
+ acct: PropTypes.string.isRequired,
+ }).isRequired,
+ accountId: PropTypes.string,
dispatch: PropTypes.func.isRequired,
attachments: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool,
@@ -68,15 +82,29 @@ class AccountGallery extends ImmutablePureComponent {
width: 323,
};
+ _load () {
+ const { accountId, dispatch } = this.props;
+
+ dispatch(expandAccountMediaTimeline(accountId));
+ }
+
componentDidMount () {
- this.props.dispatch(fetchAccount(this.props.params.accountId));
- this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId));
+ const { params: { acct }, accountId, dispatch } = this.props;
+
+ if (accountId) {
+ this._load();
+ } else {
+ dispatch(lookupAccount(acct));
+ }
}
- componentWillReceiveProps (nextProps) {
- if (nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) {
- this.props.dispatch(fetchAccount(nextProps.params.accountId));
- this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId));
+ componentDidUpdate (prevProps) {
+ const { params: { acct }, accountId, dispatch } = this.props;
+
+ if (prevProps.accountId !== accountId && accountId) {
+ this._load();
+ } else if (prevProps.params.acct !== acct) {
+ dispatch(lookupAccount(acct));
}
}
@@ -96,7 +124,7 @@ class AccountGallery extends ImmutablePureComponent {
}
handleLoadMore = maxId => {
- this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId, { maxId }));
+ this.props.dispatch(expandAccountMediaTimeline(this.props.accountId, { maxId }));
};
handleLoadOlder = e => {
@@ -166,7 +194,7 @@ class AccountGallery extends ImmutablePureComponent {
<ScrollContainer scrollKey='account_gallery' shouldUpdateScroll={shouldUpdateScroll}>
<div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
- <HeaderContainer accountId={this.props.params.accountId} />
+ <HeaderContainer accountId={this.props.accountId} />
{(suspended || blockedBy) ? (
<div className='empty-column-indicator'>
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 6b52defe4..17b693600 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -123,9 +123,9 @@ export default class Header extends ImmutablePureComponent {
{!hideTabs && (
<div className='account__section-headline'>
- <NavLink exact to={`/accounts/${account.get('id')}`}><FormattedMessage id='account.posts' defaultMessage='Toots' /></NavLink>
- <NavLink exact to={`/accounts/${account.get('id')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Toots and replies' /></NavLink>
- <NavLink exact to={`/accounts/${account.get('id')}/media`}><FormattedMessage id='account.media' defaultMessage='Media' /></NavLink>
+ <NavLink exact to={`/@${account.get('acct')}`}><FormattedMessage id='account.posts' defaultMessage='Toots' /></NavLink>
+ <NavLink exact to={`/@${account.get('acct')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Toots and replies' /></NavLink>
+ <NavLink exact to={`/@${account.get('acct')}/media`}><FormattedMessage id='account.media' defaultMessage='Media' /></NavLink>
</div>
)}
</div>
diff --git a/app/javascript/mastodon/features/account_timeline/components/moved_note.js b/app/javascript/mastodon/features/account_timeline/components/moved_note.js
index 3e090bb5f..2e32d660f 100644
--- a/app/javascript/mastodon/features/account_timeline/components/moved_note.js
+++ b/app/javascript/mastodon/features/account_timeline/components/moved_note.js
@@ -21,7 +21,7 @@ export default class MovedNote extends ImmutablePureComponent {
handleAccountClick = e => {
if (e.button === 0) {
e.preventDefault();
- this.context.router.history.push(`/accounts/${this.props.to.get('id')}`);
+ this.context.router.history.push(`/@${this.props.to.get('acct')}`);
}
e.stopPropagation();
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index fa4239d6f..c5eeec083 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -2,7 +2,7 @@ import React from 'react';
import { connect } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
-import { fetchAccount } from '../../actions/accounts';
+import { lookupAccount, fetchAccount } from '../../actions/accounts';
import { expandAccountFeaturedTimeline, expandAccountTimeline } from '../../actions/timelines';
import StatusList from '../../components/status_list';
import LoadingIndicator from '../../components/loading_indicator';
@@ -20,10 +20,19 @@ import { connectTimeline, disconnectTimeline } from 'mastodon/actions/timelines'
const emptyList = ImmutableList();
-const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => {
+const mapStateToProps = (state, { params: { acct }, withReplies = false }) => {
+ const accountId = state.getIn(['accounts_map', acct]);
+
+ if (!accountId) {
+ return {
+ isLoading: true,
+ };
+ }
+
const path = withReplies ? `${accountId}:with_replies` : accountId;
return {
+ accountId,
remote: !!(state.getIn(['accounts', accountId, 'acct']) !== state.getIn(['accounts', accountId, 'username'])),
remoteUrl: state.getIn(['accounts', accountId, 'url']),
isAccount: !!state.getIn(['accounts', accountId]),
@@ -48,7 +57,10 @@ export default @connect(mapStateToProps)
class AccountTimeline extends ImmutablePureComponent {
static propTypes = {
- params: PropTypes.object.isRequired,
+ params: PropTypes.shape({
+ acct: PropTypes.string.isRequired,
+ }).isRequired,
+ accountId: PropTypes.string,
dispatch: PropTypes.func.isRequired,
shouldUpdateScroll: PropTypes.func,
statusIds: ImmutablePropTypes.list,
@@ -64,8 +76,8 @@ class AccountTimeline extends ImmutablePureComponent {
multiColumn: PropTypes.bool,
};
- componentWillMount () {
- const { params: { accountId }, withReplies, dispatch } = this.props;
+ _load () {
+ const { accountId, withReplies, dispatch } = this.props;
dispatch(fetchAccount(accountId));
dispatch(fetchAccountIdentityProofs(accountId));
@@ -81,29 +93,32 @@ class AccountTimeline extends ImmutablePureComponent {
}
}
- componentWillReceiveProps (nextProps) {
- const { dispatch } = this.props;
+ componentDidMount () {
+ const { params: { acct }, accountId, dispatch } = this.props;
- if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) {
- dispatch(fetchAccount(nextProps.params.accountId));
- dispatch(fetchAccountIdentityProofs(nextProps.params.accountId));
+ if (accountId) {
+ this._load();
+ } else {
+ dispatch(lookupAccount(acct));
+ }
+ }
- if (!nextProps.withReplies) {
- dispatch(expandAccountFeaturedTimeline(nextProps.params.accountId));
- }
+ componentDidUpdate (prevProps) {
+ const { params: { acct }, accountId, dispatch } = this.props;
- dispatch(expandAccountTimeline(nextProps.params.accountId, { withReplies: nextProps.params.withReplies }));
+ if (prevProps.accountId !== accountId && accountId) {
+ this._load();
+ } else if (prevProps.params.acct !== acct) {
+ dispatch(lookupAccount(acct));
}
- if (nextProps.params.accountId === me && this.props.params.accountId !== me) {
- dispatch(connectTimeline(`account:${me}`));
- } else if (this.props.params.accountId === me && nextProps.params.accountId !== me) {
+ if (prevProps.accountId === me && accountId !== me) {
dispatch(disconnectTimeline(`account:${me}`));
}
}
componentWillUnmount () {
- const { dispatch, params: { accountId } } = this.props;
+ const { dispatch, accountId } = this.props;
if (accountId === me) {
dispatch(disconnectTimeline(`account:${me}`));
@@ -111,7 +126,7 @@ class AccountTimeline extends ImmutablePureComponent {
}
handleLoadMore = maxId => {
- this.props.dispatch(expandAccountTimeline(this.props.params.accountId, { maxId, withReplies: this.props.withReplies }));
+ this.props.dispatch(expandAccountTimeline(this.props.accountId, { maxId, withReplies: this.props.withReplies }));
}
render () {
@@ -153,7 +168,7 @@ class AccountTimeline extends ImmutablePureComponent {
<ColumnBackButton multiColumn={multiColumn} />
<StatusList
- prepend={<HeaderContainer accountId={this.props.params.accountId} />}
+ prepend={<HeaderContainer accountId={this.props.accountId} />}
alwaysPrepend
append={remoteMessage}
scrollKey='account_timeline'
diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js
index 840d0a3da..e6ba7d8b7 100644
--- a/app/javascript/mastodon/features/compose/components/navigation_bar.js
+++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js
@@ -19,13 +19,13 @@ export default class NavigationBar extends ImmutablePureComponent {
render () {
return (
<div className='navigation-bar'>
- <Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}>
+ <Permalink href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}>
<span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
<Avatar account={this.props.account} size={48} />
</Permalink>
<div className='navigation-bar__profile'>
- <Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}>
+ <Permalink href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}>
<strong className='navigation-bar__profile-account'>@{this.props.account.get('acct')}</strong>
</Permalink>
diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js
index a1d5c420c..863defb76 100644
--- a/app/javascript/mastodon/features/compose/components/reply_indicator.js
+++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js
@@ -32,7 +32,7 @@ class ReplyIndicator extends ImmutablePureComponent {
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
- this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
}
diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js
index e2de8b0e6..2ca14a2dd 100644
--- a/app/javascript/mastodon/features/compose/index.js
+++ b/app/javascript/mastodon/features/compose/index.js
@@ -99,16 +99,16 @@ class Compose extends React.PureComponent {
<nav className='drawer__header'>
<Link to='/getting-started' className='drawer__tab' title={intl.formatMessage(messages.start)} aria-label={intl.formatMessage(messages.start)}><Icon id='bars' fixedWidth /></Link>
{!columns.some(column => column.get('id') === 'HOME') && (
- <Link to='/timelines/home' className='drawer__tab' title={intl.formatMessage(messages.home_timeline)} aria-label={intl.formatMessage(messages.home_timeline)}><Icon id='home' fixedWidth /></Link>
+ <Link to='/home' className='drawer__tab' title={intl.formatMessage(messages.home_timeline)} aria-label={intl.formatMessage(messages.home_timeline)}><Icon id='home' fixedWidth /></Link>
)}
{!columns.some(column => column.get('id') === 'NOTIFICATIONS') && (
<Link to='/notifications' className='drawer__tab' title={intl.formatMessage(messages.notifications)} aria-label={intl.formatMessage(messages.notifications)}><Icon id='bell' fixedWidth /></Link>
)}
{!columns.some(column => column.get('id') === 'COMMUNITY') && (
- <Link to='/timelines/public/local' className='drawer__tab' title={intl.formatMessage(messages.community)} aria-label={intl.formatMessage(messages.community)}><Icon id='users' fixedWidth /></Link>
+ <Link to='/local' className='drawer__tab' title={intl.formatMessage(messages.community)} aria-label={intl.formatMessage(messages.community)}><Icon id='users' fixedWidth /></Link>
)}
{!columns.some(column => column.get('id') === 'PUBLIC') && (
- <Link to='/timelines/public' className='drawer__tab' title={intl.formatMessage(messages.public)} aria-label={intl.formatMessage(messages.public)}><Icon id='globe' fixedWidth /></Link>
+ <Link to='/federated' className='drawer__tab' title={intl.formatMessage(messages.public)} aria-label={intl.formatMessage(messages.public)}><Icon id='globe' fixedWidth /></Link>
)}
<a href='/settings/preferences' className='drawer__tab' title={intl.formatMessage(messages.preferences)} aria-label={intl.formatMessage(messages.preferences)}><Icon id='cog' fixedWidth /></a>
<a href='/auth/sign_out' className='drawer__tab' title={intl.formatMessage(messages.logout)} aria-label={intl.formatMessage(messages.logout)} onClick={this.handleLogoutClick}><Icon id='sign-out' fixedWidth /></a>
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.js b/app/javascript/mastodon/features/direct_timeline/components/conversation.js
index 43e1d77b9..c4f7098c5 100644
--- a/app/javascript/mastodon/features/direct_timeline/components/conversation.js
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.js
@@ -133,7 +133,7 @@ class Conversation extends ImmutablePureComponent {
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete });
- const names = accounts.map(a => <Permalink to={`/accounts/${a.get('id')}`} href={a.get('url')} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Permalink>).reduce((prev, cur) => [prev, ', ', cur]);
+ const names = accounts.map(a => <Permalink to={`/@${a.get('acct')}`} href={a.get('url')} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Permalink>).reduce((prev, cur) => [prev, ', ', cur]);
const handlers = {
reply: this.handleReply,
diff --git a/app/javascript/mastodon/features/directory/components/account_card.js b/app/javascript/mastodon/features/directory/components/account_card.js
index 8f0e8db4b..03e13f28e 100644
--- a/app/javascript/mastodon/features/directory/components/account_card.js
+++ b/app/javascript/mastodon/features/directory/components/account_card.js
@@ -213,7 +213,7 @@ class AccountCard extends ImmutablePureComponent {
<Permalink
className='directory__card__bar__name'
href={account.get('url')}
- to={`/accounts/${account.get('id')}`}
+ to={`/@${account.get('acct')}`}
>
<Avatar account={account} size={48} />
<DisplayName account={account} />
diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
index 8269f5ae4..263a7ae16 100644
--- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
+++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
@@ -30,7 +30,7 @@ class AccountAuthorize extends ImmutablePureComponent {
return (
<div className='account-authorize__wrapper'>
<div className='account-authorize'>
- <Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name'>
+ <Permalink href={account.get('url')} to={`/@${account.get('acct')}`} className='detailed-status__display-name'>
<div className='account-authorize__avatar'><Avatar account={account} size={48} /></div>
<DisplayName account={account} />
</Permalink>
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js
index ae00d13d3..533e83841 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.js
@@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { debounce } from 'lodash';
import LoadingIndicator from '../../components/loading_indicator';
import {
- fetchAccount,
+ lookupAccount,
fetchFollowers,
expandFollowers,
} from '../../actions/accounts';
@@ -19,15 +19,26 @@ import ScrollableList from '../../components/scrollable_list';
import MissingIndicator from 'mastodon/components/missing_indicator';
import TimelineHint from 'mastodon/components/timeline_hint';
-const mapStateToProps = (state, props) => ({
- remote: !!(state.getIn(['accounts', props.params.accountId, 'acct']) !== state.getIn(['accounts', props.params.accountId, 'username'])),
- remoteUrl: state.getIn(['accounts', props.params.accountId, 'url']),
- isAccount: !!state.getIn(['accounts', props.params.accountId]),
- accountIds: state.getIn(['user_lists', 'followers', props.params.accountId, 'items']),
- hasMore: !!state.getIn(['user_lists', 'followers', props.params.accountId, 'next']),
- isLoading: state.getIn(['user_lists', 'followers', props.params.accountId, 'isLoading'], true),
- blockedBy: state.getIn(['relationships', props.params.accountId, 'blocked_by'], false),
-});
+const mapStateToProps = (state, { params: { acct } }) => {
+ const accountId = state.getIn(['accounts_map', acct]);
+
+ if (!accountId) {
+ return {
+ isLoading: true,
+ };
+ }
+
+ return {
+ accountId,
+ remote: !!(state.getIn(['accounts', accountId, 'acct']) !== state.getIn(['accounts', accountId, 'username'])),
+ remoteUrl: state.getIn(['accounts', accountId, 'url']),
+ isAccount: !!state.getIn(['accounts', accountId]),
+ accountIds: state.getIn(['user_lists', 'followers', accountId, 'items']),
+ hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
+ isLoading: state.getIn(['user_lists', 'followers', accountId, 'isLoading'], true),
+ blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false),
+ };
+};
const RemoteHint = ({ url }) => (
<TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.followers' defaultMessage='Followers' />} />
@@ -41,7 +52,10 @@ export default @connect(mapStateToProps)
class Followers extends ImmutablePureComponent {
static propTypes = {
- params: PropTypes.object.isRequired,
+ params: PropTypes.shape({
+ acct: PropTypes.string.isRequired,
+ }).isRequired,
+ accountId: PropTypes.string,
dispatch: PropTypes.func.isRequired,
shouldUpdateScroll: PropTypes.func,
accountIds: ImmutablePropTypes.list,
@@ -54,22 +68,34 @@ class Followers extends ImmutablePureComponent {
multiColumn: PropTypes.bool,
};
- componentWillMount () {
- if (!this.props.accountIds) {
- this.props.dispatch(fetchAccount(this.props.params.accountId));
- this.props.dispatch(fetchFollowers(this.props.params.accountId));
+ _load () {
+ const { accountId, dispatch } = this.props;
+
+ dispatch(fetchFollowers(accountId));
+ }
+
+ componentDidMount () {
+ const { params: { acct }, accountId, dispatch } = this.props;
+
+ if (accountId) {
+ this._load();
+ } else {
+ dispatch(lookupAccount(acct));
}
}
- componentWillReceiveProps (nextProps) {
- if (nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) {
- this.props.dispatch(fetchAccount(nextProps.params.accountId));
- this.props.dispatch(fetchFollowers(nextProps.params.accountId));
+ componentDidUpdate (prevProps) {
+ const { params: { acct }, accountId, dispatch } = this.props;
+
+ if (prevProps.accountId !== accountId && accountId) {
+ this._load();
+ } else if (prevProps.params.acct !== acct) {
+ dispatch(lookupAccount(acct));
}
}
handleLoadMore = debounce(() => {
- this.props.dispatch(expandFollowers(this.props.params.accountId));
+ this.props.dispatch(expandFollowers(this.props.accountId));
}, 300, { leading: true });
render () {
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js
index 666ec7a7f..c302706d5 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.js
@@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { debounce } from 'lodash';
import LoadingIndicator from '../../components/loading_indicator';
import {
- fetchAccount,
+ lookupAccount,
fetchFollowing,
expandFollowing,
} from '../../actions/accounts';
@@ -19,15 +19,26 @@ import ScrollableList from '../../components/scrollable_list';
import MissingIndicator from 'mastodon/components/missing_indicator';
import TimelineHint from 'mastodon/components/timeline_hint';
-const mapStateToProps = (state, props) => ({
- remote: !!(state.getIn(['accounts', props.params.accountId, 'acct']) !== state.getIn(['accounts', props.params.accountId, 'username'])),
- remoteUrl: state.getIn(['accounts', props.params.accountId, 'url']),
- isAccount: !!state.getIn(['accounts', props.params.accountId]),
- accountIds: state.getIn(['user_lists', 'following', props.params.accountId, 'items']),
- hasMore: !!state.getIn(['user_lists', 'following', props.params.accountId, 'next']),
- isLoading: state.getIn(['user_lists', 'following', props.params.accountId, 'isLoading'], true),
- blockedBy: state.getIn(['relationships', props.params.accountId, 'blocked_by'], false),
-});
+const mapStateToProps = (state, { params: { acct } }) => {
+ const accountId = state.getIn(['accounts_map', acct]);
+
+ if (!accountId) {
+ return {
+ isLoading: true,
+ };
+ }
+
+ return {
+ accountId,
+ remote: !!(state.getIn(['accounts', accountId, 'acct']) !== state.getIn(['accounts', accountId, 'username'])),
+ remoteUrl: state.getIn(['accounts', accountId, 'url']),
+ isAccount: !!state.getIn(['accounts', accountId]),
+ accountIds: state.getIn(['user_lists', 'following', accountId, 'items']),
+ hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
+ isLoading: state.getIn(['user_lists', 'following', accountId, 'isLoading'], true),
+ blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false),
+ };
+};
const RemoteHint = ({ url }) => (
<TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.follows' defaultMessage='Follows' />} />
@@ -41,7 +52,10 @@ export default @connect(mapStateToProps)
class Following extends ImmutablePureComponent {
static propTypes = {
- params: PropTypes.object.isRequired,
+ params: PropTypes.shape({
+ acct: PropTypes.string.isRequired,
+ }).isRequired,
+ accountId: PropTypes.string,
dispatch: PropTypes.func.isRequired,
shouldUpdateScroll: PropTypes.func,
accountIds: ImmutablePropTypes.list,
@@ -54,22 +68,34 @@ class Following extends ImmutablePureComponent {
multiColumn: PropTypes.bool,
};
- componentWillMount () {
- if (!this.props.accountIds) {
- this.props.dispatch(fetchAccount(this.props.params.accountId));
- this.props.dispatch(fetchFollowing(this.props.params.accountId));
+ _load () {
+ const { accountId, dispatch } = this.props;
+
+ dispatch(fetchFollowing(accountId));
+ }
+
+ componentDidMount () {
+ const { params: { acct }, accountId, dispatch } = this.props;
+
+ if (accountId) {
+ this._load();
+ } else {
+ dispatch(lookupAccount(acct));
}
}
- componentWillReceiveProps (nextProps) {
- if (nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) {
- this.props.dispatch(fetchAccount(nextProps.params.accountId));
- this.props.dispatch(fetchFollowing(nextProps.params.accountId));
+ componentDidUpdate (prevProps) {
+ const { params: { acct }, accountId, dispatch } = this.props;
+
+ if (prevProps.accountId !== accountId && accountId) {
+ this._load();
+ } else if (prevProps.params.acct !== acct) {
+ dispatch(lookupAccount(acct));
}
}
handleLoadMore = debounce(() => {
- this.props.dispatch(expandFollowing(this.props.params.accountId));
+ this.props.dispatch(expandFollowing(this.props.accountId));
}, 300, { leading: true });
render () {
diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.js b/app/javascript/mastodon/features/getting_started/components/announcements.js
index ff1566e05..24db8cede 100644
--- a/app/javascript/mastodon/features/getting_started/components/announcements.js
+++ b/app/javascript/mastodon/features/getting_started/components/announcements.js
@@ -87,7 +87,7 @@ class Content extends ImmutablePureComponent {
onMentionClick = (mention, e) => {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
- this.context.router.history.push(`/accounts/${mention.get('id')}`);
+ this.context.router.history.push(`/@${mention.get('acct')}`);
}
}
@@ -96,14 +96,14 @@ class Content extends ImmutablePureComponent {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
- this.context.router.history.push(`/timelines/tag/${hashtag}`);
+ this.context.router.history.push(`/tags/${hashtag}`);
}
}
onStatusClick = (status, e) => {
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
- this.context.router.history.push(`/statuses/${status.get('id')}`);
+ this.context.router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
}
}
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index 1b9994612..88762d607 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -82,7 +82,7 @@ class GettingStarted extends ImmutablePureComponent {
const { fetchFollowRequests, multiColumn } = this.props;
if (!multiColumn && window.innerWidth >= NAVIGATION_PANEL_BREAKPOINT) {
- this.context.router.history.replace('/timelines/home');
+ this.context.router.history.replace('/home');
return;
}
@@ -98,15 +98,15 @@ class GettingStarted extends ImmutablePureComponent {
if (multiColumn) {
navItems.push(
<ColumnSubheading key='header-discover' text={intl.formatMessage(messages.discover)} />,
- <ColumnLink key='community_timeline' icon='users' text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />,
- <ColumnLink key='public_timeline' icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />,
+ <ColumnLink key='community_timeline' icon='users' text={intl.formatMessage(messages.community_timeline)} to='/public/local' />,
+ <ColumnLink key='public_timeline' icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/public' />,
);
height += 34 + 48*2;
if (profile_directory) {
navItems.push(
- <ColumnLink key='directory' icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />,
+ <ColumnLink key='directory' icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/explore' />,
);
height += 48;
@@ -119,7 +119,7 @@ class GettingStarted extends ImmutablePureComponent {
height += 34;
} else if (profile_directory) {
navItems.push(
- <ColumnLink key='directory' icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />,
+ <ColumnLink key='directory' icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/explore' />,
);
height += 48;
@@ -127,13 +127,13 @@ class GettingStarted extends ImmutablePureComponent {
if (multiColumn && !columns.find(item => item.get('id') === 'HOME')) {
navItems.push(
- <ColumnLink key='home' icon='home' text={intl.formatMessage(messages.home_timeline)} to='/timelines/home' />,
+ <ColumnLink key='home' icon='home' text={intl.formatMessage(messages.home_timeline)} to='/home' />,
);
height += 48;
}
navItems.push(
- <ColumnLink key='direct' icon='envelope' text={intl.formatMessage(messages.direct)} to='/timelines/direct' />,
+ <ColumnLink key='direct' icon='envelope' text={intl.formatMessage(messages.direct)} to='/conversations' />,
<ColumnLink key='bookmark' icon='bookmark' text={intl.formatMessage(messages.bookmarks)} to='/bookmarks' />,
<ColumnLink key='favourites' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
<ColumnLink key='lists' icon='list-ul' text={intl.formatMessage(messages.lists)} to='/lists' />,
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js
index 577ff33bb..0d7914f1f 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.js
@@ -153,7 +153,7 @@ class HomeTimeline extends React.PureComponent {
scrollKey={`home_timeline-${columnId}`}
onLoadMore={this.handleLoadMore}
timelineId='home'
- emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />}
+ emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />}
shouldUpdateScroll={shouldUpdateScroll}
bindToDocument={!multiColumn}
/>
diff --git a/app/javascript/mastodon/features/lists/index.js b/app/javascript/mastodon/features/lists/index.js
index ca1fa1f5e..b52116fc2 100644
--- a/app/javascript/mastodon/features/lists/index.js
+++ b/app/javascript/mastodon/features/lists/index.js
@@ -74,7 +74,7 @@ class Lists extends ImmutablePureComponent {
bindToDocument={!multiColumn}
>
{lists.map(list =>
- <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />,
+ <ColumnLink key={list.get('id')} to={`/lists/${list.get('id')}`} icon='list-ul' text={list.get('title')} />,
)}
</ScrollableList>
</Column>
diff --git a/app/javascript/mastodon/features/notifications/components/follow_request.js b/app/javascript/mastodon/features/notifications/components/follow_request.js
index a80cfb2fa..9ef3fde7e 100644
--- a/app/javascript/mastodon/features/notifications/components/follow_request.js
+++ b/app/javascript/mastodon/features/notifications/components/follow_request.js
@@ -42,7 +42,7 @@ class FollowRequest extends ImmutablePureComponent {
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')}`}>
+ <Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
<DisplayName account={account} />
</Permalink>
diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js
index 94fdbd6f4..f9f8a87f2 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.js
+++ b/app/javascript/mastodon/features/notifications/components/notification.js
@@ -68,7 +68,7 @@ class Notification extends ImmutablePureComponent {
const { notification } = this.props;
if (notification.get('status')) {
- this.context.router.history.push(`/statuses/${notification.get('status')}`);
+ this.context.router.history.push(`/@${notification.getIn(['status', 'account', 'acct'])}/${notification.get('status')}`);
} else {
this.handleOpenProfile();
}
@@ -76,7 +76,7 @@ class Notification extends ImmutablePureComponent {
handleOpenProfile = () => {
const { notification } = this.props;
- this.context.router.history.push(`/accounts/${notification.getIn(['account', 'id'])}`);
+ this.context.router.history.push(`/@${notification.getIn(['account', 'acct'])}`);
}
handleMention = e => {
@@ -315,7 +315,7 @@ class Notification extends ImmutablePureComponent {
const { notification } = this.props;
const account = notification.get('account');
const displayNameHtml = { __html: account.get('display_name_html') };
- const link = <bdi><Permalink className='notification__display-name' href={account.get('url')} title={account.get('acct')} to={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
+ const link = <bdi><Permalink className='notification__display-name' href={account.get('url')} title={account.get('acct')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
switch(notification.get('type')) {
case 'follow':
diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.js b/app/javascript/mastodon/features/picture_in_picture/components/footer.js
index 1ecb18bf8..9f237da46 100644
--- a/app/javascript/mastodon/features/picture_in_picture/components/footer.js
+++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.js
@@ -116,7 +116,7 @@ class Footer extends ImmutablePureComponent {
const { status } = this.props;
- router.history.push(`/statuses/${status.get('id')}`);
+ router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
}
render () {
diff --git a/app/javascript/mastodon/features/picture_in_picture/components/header.js b/app/javascript/mastodon/features/picture_in_picture/components/header.js
index 7dd199b75..e05d8c62e 100644
--- a/app/javascript/mastodon/features/picture_in_picture/components/header.js
+++ b/app/javascript/mastodon/features/picture_in_picture/components/header.js
@@ -34,7 +34,7 @@ class Header extends ImmutablePureComponent {
return (
<div className='picture-in-picture__header'>
- <Link to={`/statuses/${statusId}`} className='picture-in-picture__header__account'>
+ <Link to={`/@${account.get('acct')}/${statusId}`} className='picture-in-picture__header__account'>
<Avatar account={account} size={36} />
<DisplayName account={account} />
</Link>
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index 043a749ed..72ddeb2b2 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -55,7 +55,7 @@ class DetailedStatus extends ImmutablePureComponent {
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.context.router) {
e.preventDefault();
- this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
e.stopPropagation();
@@ -195,7 +195,7 @@ class DetailedStatus extends ImmutablePureComponent {
reblogLink = (
<React.Fragment>
<React.Fragment> ยท </React.Fragment>
- <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
+ <Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} className='detailed-status__link'>
<Icon id={reblogIcon} />
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
@@ -219,7 +219,7 @@ class DetailedStatus extends ImmutablePureComponent {
if (this.context.router) {
favouriteLink = (
- <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
+ <Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link'>
<Icon id='star' />
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('favourites_count')} />
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index df8362a1b..d1f63d425 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -396,7 +396,7 @@ class Status extends ImmutablePureComponent {
}
handleHotkeyOpenProfile = () => {
- this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
handleHotkeyToggleHidden = () => {
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js
index 83229833b..f8a344690 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.js
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.js
@@ -68,7 +68,7 @@ class BoostModal extends ImmutablePureComponent {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.props.onClose();
- this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
+ this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
}
}
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index 6837450eb..46b0fda8a 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -191,7 +191,7 @@ class ColumnsArea extends ImmutablePureComponent {
const columnIndex = getIndex(this.context.router.history.location.pathname);
if (singleColumn) {
- const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><Icon id='pencil' /></Link>;
+ const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/publish' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><Icon id='pencil' /></Link>;
const content = columnIndex !== -1 ? (
<ReactSwipeableViews key='content' hysteresis={0.2} threshold={15} index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }} disabled={disableSwiping}>
diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.js b/app/javascript/mastodon/features/ui/components/compose_panel.js
index 3d0c48c7a..82a21d515 100644
--- a/app/javascript/mastodon/features/ui/components/compose_panel.js
+++ b/app/javascript/mastodon/features/ui/components/compose_panel.js
@@ -6,6 +6,7 @@ import ComposeFormContainer from 'mastodon/features/compose/containers/compose_f
import NavigationContainer from 'mastodon/features/compose/containers/navigation_container';
import LinkFooter from './link_footer';
import { changeComposing } from 'mastodon/actions/compose';
+import { me } from 'mastodon/initial_state';
export default @connect()
class ComposePanel extends React.PureComponent {
@@ -26,8 +27,10 @@ class ComposePanel extends React.PureComponent {
return (
<div className='compose-panel' onFocus={this.onFocus}>
<SearchContainer openInRoute />
- <NavigationContainer onClose={this.onBlur} />
- <ComposeFormContainer singleColumn />
+
+ {me && <NavigationContainer onClose={this.onBlur} />}
+ {me && <ComposeFormContainer singleColumn />}
+
<LinkFooter withHotkeys />
</div>
);
diff --git a/app/javascript/mastodon/features/ui/components/list_panel.js b/app/javascript/mastodon/features/ui/components/list_panel.js
index 1f7ec683a..411f62508 100644
--- a/app/javascript/mastodon/features/ui/components/list_panel.js
+++ b/app/javascript/mastodon/features/ui/components/list_panel.js
@@ -46,7 +46,7 @@ class ListPanel extends ImmutablePureComponent {
<hr />
{lists.map(list => (
- <NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/timelines/list/${list.get('id')}`}><Icon className='column-link__icon' id='list-ul' fixedWidth />{list.get('title')}</NavLink>
+ <NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/lists/${list.get('id')}`}><Icon className='column-link__icon' id='list-ul' fixedWidth />{list.get('title')}</NavLink>
))}
</div>
);
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js
index 08da10330..dc2194664 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.js
@@ -152,13 +152,6 @@ class MediaModal extends ImmutablePureComponent {
}));
};
- handleStatusClick = e => {
- if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
- e.preventDefault();
- this.context.router.history.push(`/statuses/${this.props.statusId}`);
- }
- }
-
render () {
const { media, statusId, intl, onClose } = this.props;
const { navigationHidden } = this.state;
diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js
index 0c12852f5..26b2cfc87 100644
--- a/app/javascript/mastodon/features/ui/components/navigation_panel.js
+++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js
@@ -10,16 +10,16 @@ import TrendsContainer from 'mastodon/features/getting_started/containers/trends
const NavigationPanel = () => (
<div className='navigation-panel'>
- <NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon className='column-link__icon' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>
<FollowRequestsNavLink />
- <NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
- <NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
- <NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' id='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
+ <NavLink className='column-link column-link--transparent' exact to='/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/conversations'><Icon className='column-link__icon' id='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/favourites'><Icon className='column-link__icon' id='star' fixedWidth /><FormattedMessage id='navigation_bar.favourites' defaultMessage='Favourites' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' id='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' id='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
- {profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
+ {profile_directory && <NavLink className='column-link column-link--transparent' to='/explore'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
<ListPanel />
diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js
index 1911da8ba..a023bcf34 100644
--- a/app/javascript/mastodon/features/ui/components/tabs_bar.js
+++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js
@@ -8,10 +8,10 @@ import Icon from 'mastodon/components/icon';
import NotificationsCounterIcon from './notifications_counter_icon';
export const links = [
- <NavLink className='tabs-bar__link' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
+ <NavLink className='tabs-bar__link' to='/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
<NavLink className='tabs-bar__link' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>,
- <NavLink className='tabs-bar__link' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
- <NavLink className='tabs-bar__link' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
+ <NavLink className='tabs-bar__link' to='/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
+ <NavLink className='tabs-bar__link' exact to='/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
<NavLink className='tabs-bar__link optional' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><Icon id='search' fixedWidth /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
<NavLink className='tabs-bar__link' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='bars' ><Icon id='bars' fixedWidth /></NavLink>,
];
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index 507ac1df1..c0b7bafce 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -147,7 +147,7 @@ class SwitchingColumnsArea extends React.PureComponent {
render () {
const { children, mobile } = this.props;
- const redirect = mobile ? <Redirect from='/' to='/timelines/home' exact /> : <Redirect from='/' to='/getting-started' exact />;
+ const redirect = mobile ? <Redirect from='/' to='/home' exact /> : <Redirect from='/' to='/getting-started' exact />;
return (
<ColumnsAreaContainer ref={this.setRef} singleColumn={mobile}>
@@ -155,31 +155,29 @@ class SwitchingColumnsArea extends React.PureComponent {
{redirect}
<WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
<WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
- <WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
-
+ <WrappedRoute path='/home' component={HomeTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/public' exact component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/public/local' exact component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/conversations' component={DirectTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/tags/:id' component={HashtagTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/lists/:id' component={ListTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
<WrappedRoute path='/notifications' component={Notifications} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
<WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
-
<WrappedRoute path='/search' component={Search} content={children} />
- <WrappedRoute path='/directory' component={Directory} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
-
- <WrappedRoute path='/statuses/new' component={Compose} content={children} />
- <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/explore' component={Directory} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/publish' component={Compose} content={children} />
- <WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, withReplies: true }} />
- <WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
- <WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct' exact component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/with_replies' component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, withReplies: true }} />
+ <WrappedRoute path='/@:acct/followers' component={Followers} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/following' component={Following} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/media' component={AccountGallery} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/tagged/:tag' component={AccountTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/:statusId/reblogs' component={Reblogs} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
+ <WrappedRoute path='/@:acct/:statusId/favourites' component={Favourites} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
<WrappedRoute path='/follow_requests' component={FollowRequests} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
<WrappedRoute path='/blocks' component={Blocks} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
@@ -447,7 +445,7 @@ class UI extends React.PureComponent {
}
handleHotkeyGoToHome = () => {
- this.context.router.history.push('/timelines/home');
+ this.context.router.history.push('/home');
}
handleHotkeyGoToNotifications = () => {
@@ -455,15 +453,15 @@ class UI extends React.PureComponent {
}
handleHotkeyGoToLocal = () => {
- this.context.router.history.push('/timelines/public/local');
+ this.context.router.history.push('/public/local');
}
handleHotkeyGoToFederated = () => {
- this.context.router.history.push('/timelines/public');
+ this.context.router.history.push('/public');
}
handleHotkeyGoToDirect = () => {
- this.context.router.history.push('/timelines/direct');
+ this.context.router.history.push('/conversations');
}
handleHotkeyGoToStart = () => {
@@ -479,7 +477,7 @@ class UI extends React.PureComponent {
}
handleHotkeyGoToProfile = () => {
- this.context.router.history.push(`/accounts/${me}`);
+ this.context.router.history.push(`/accounts/${me}`); // FIXME
}
handleHotkeyGoToBlocked = () => {
diff --git a/app/javascript/mastodon/main.js b/app/javascript/mastodon/main.js
index bda51f692..91d36405b 100644
--- a/app/javascript/mastodon/main.js
+++ b/app/javascript/mastodon/main.js
@@ -13,9 +13,9 @@ function main() {
if (window.history && history.replaceState) {
const { pathname, search, hash } = window.location;
const path = pathname + search + hash;
- if (!(/^\/web($|\/)/).test(path)) {
- history.replaceState(null, document.title, `/web${path}`);
- }
+ //if (!(/^\/web($|\/)/).test(path)) {
+ // history.replaceState(null, document.title, `/web${path}`);
+ //}
}
ready(() => {
diff --git a/app/javascript/mastodon/reducers/accounts_map.js b/app/javascript/mastodon/reducers/accounts_map.js
new file mode 100644
index 000000000..e0d42e9cd
--- /dev/null
+++ b/app/javascript/mastodon/reducers/accounts_map.js
@@ -0,0 +1,15 @@
+import { ACCOUNT_IMPORT, ACCOUNTS_IMPORT } from '../actions/importer';
+import { Map as ImmutableMap } from 'immutable';
+
+const initialState = ImmutableMap();
+
+export default function accountsMap(state = initialState, action) {
+ switch(action.type) {
+ case ACCOUNT_IMPORT:
+ return state.set(action.account.acct, action.account.id);
+ case ACCOUNTS_IMPORT:
+ return state.withMutations(map => action.accounts.forEach(account => map.set(account.acct, account.id)));
+ default:
+ return state;
+ }
+};
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index 3b3c5ae29..e518c8228 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -38,6 +38,7 @@ import missed_updates from './missed_updates';
import announcements from './announcements';
import markers from './markers';
import picture_in_picture from './picture_in_picture';
+import accounts_map from './accounts_map';
const reducers = {
announcements,
@@ -52,6 +53,7 @@ const reducers = {
status_lists,
accounts,
accounts_counters,
+ accounts_map,
statuses,
relationships,
settings,
diff --git a/app/javascript/mastodon/service_worker/web_push_notifications.js b/app/javascript/mastodon/service_worker/web_push_notifications.js
index 958e5fc12..2da78006b 100644
--- a/app/javascript/mastodon/service_worker/web_push_notifications.js
+++ b/app/javascript/mastodon/service_worker/web_push_notifications.js
@@ -90,7 +90,7 @@ const handlePush = (event) => {
options.tag = notification.id;
options.badge = '/badge.png';
options.image = notification.status && notification.status.media_attachments.length > 0 && notification.status.media_attachments[0].preview_url || undefined;
- options.data = { access_token, preferred_locale, id: notification.status ? notification.status.id : notification.account.id, url: notification.status ? `/web/statuses/${notification.status.id}` : `/web/accounts/${notification.account.id}` };
+ options.data = { access_token, preferred_locale, id: notification.status ? notification.status.id : notification.account.id, url: notification.status ? `/@${notification.account.acct}/${notification.status.id}` : `/@${notification.account.acct}` };
if (notification.status && notification.status.spoiler_text || notification.status.sensitive) {
options.data.hiddenBody = htmlToPlainText(notification.status.content);