|
|
@@ -104,125 +104,6 @@ addLocaleData([ |
|
|
|
...tr, |
|
|
|
]); |
|
|
|
|
|
|
|
const getTopWhenReplacing = (previous, { location }) => location && location.action === 'REPLACE' && [0, 0]; |
|
|
|
|
|
|
|
const hiddenColumnContainerStyle = { |
|
|
|
position: 'absolute', |
|
|
|
left: '0', |
|
|
|
top: '0', |
|
|
|
visibility: 'hidden' |
|
|
|
}; |
|
|
|
|
|
|
|
class Container extends React.PureComponent { |
|
|
|
|
|
|
|
constructor(props) { |
|
|
|
super(props); |
|
|
|
|
|
|
|
this.state = { |
|
|
|
renderedPersistents: [], |
|
|
|
unrenderedPersistents: [], |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
componentWillMount () { |
|
|
|
this.unlistenHistory = null; |
|
|
|
|
|
|
|
this.setState(() => { |
|
|
|
return { |
|
|
|
mountImpersistent: false, |
|
|
|
renderedPersistents: [], |
|
|
|
unrenderedPersistents: [ |
|
|
|
{pathname: '/timelines/home', component: HomeTimeline}, |
|
|
|
{pathname: '/timelines/public', component: PublicTimeline}, |
|
|
|
{pathname: '/timelines/public/local', component: CommunityTimeline}, |
|
|
|
|
|
|
|
{pathname: '/notifications', component: Notifications}, |
|
|
|
{pathname: '/favourites', component: FavouritedStatuses} |
|
|
|
], |
|
|
|
}; |
|
|
|
}, () => { |
|
|
|
if (this.unlistenHistory) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.unlistenHistory = browserHistory.listen(location => { |
|
|
|
const pathname = location.pathname.replace(/\/$/, '').toLowerCase(); |
|
|
|
|
|
|
|
this.setState(oldState => { |
|
|
|
let persistentMatched = false; |
|
|
|
|
|
|
|
const newState = { |
|
|
|
renderedPersistents: oldState.renderedPersistents.map(persistent => { |
|
|
|
const givenMatched = persistent.pathname === pathname; |
|
|
|
|
|
|
|
if (givenMatched) { |
|
|
|
persistentMatched = true; |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
hidden: !givenMatched, |
|
|
|
pathname: persistent.pathname, |
|
|
|
component: persistent.component |
|
|
|
}; |
|
|
|
}), |
|
|
|
}; |
|
|
|
|
|
|
|
if (!persistentMatched) { |
|
|
|
newState.unrenderedPersistents = []; |
|
|
|
|
|
|
|
oldState.unrenderedPersistents.forEach(persistent => { |
|
|
|
if (persistent.pathname === pathname) { |
|
|
|
persistentMatched = true; |
|
|
|
|
|
|
|
newState.renderedPersistents.push({ |
|
|
|
hidden: false, |
|
|
|
pathname: persistent.pathname, |
|
|
|
component: persistent.component |
|
|
|
}); |
|
|
|
} else { |
|
|
|
newState.unrenderedPersistents.push(persistent); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
newState.mountImpersistent = !persistentMatched; |
|
|
|
|
|
|
|
return newState; |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
componentWillUnmount () { |
|
|
|
if (this.unlistenHistory) { |
|
|
|
this.unlistenHistory(); |
|
|
|
} |
|
|
|
|
|
|
|
this.unlistenHistory = "done"; |
|
|
|
} |
|
|
|
|
|
|
|
render () { |
|
|
|
// Hide some components rather than unmounting them to allow to show again |
|
|
|
// quickly and keep the view state such as the scrolled offset. |
|
|
|
const persistentsView = this.state.renderedPersistents.map((persistent) => |
|
|
|
<div aria-hidden={persistent.hidden} key={persistent.pathname} className='mastodon-column-container' style={persistent.hidden ? hiddenColumnContainerStyle : null}> |
|
|
|
<persistent.component shouldUpdateScroll={persistent.hidden ? Function.prototype : getTopWhenReplacing} /> |
|
|
|
</div> |
|
|
|
); |
|
|
|
|
|
|
|
return ( |
|
|
|
<UI> |
|
|
|
{this.state.mountImpersistent && this.props.children} |
|
|
|
{persistentsView} |
|
|
|
</UI> |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Container.propTypes = { |
|
|
|
children: PropTypes.node, |
|
|
|
}; |
|
|
|
|
|
|
|
class Mastodon extends React.PureComponent { |
|
|
|
|
|
|
|
componentDidMount() { |
|
|
@@ -304,11 +185,17 @@ class Mastodon extends React.PureComponent { |
|
|
|
<IntlProvider locale={locale} messages={getMessagesForLocale(locale)}> |
|
|
|
<Provider store={store}> |
|
|
|
<Router history={browserHistory} render={applyRouterMiddleware(useScroll())}> |
|
|
|
<Route path='/' component={Container}> |
|
|
|
<Route path='/' component={UI}> |
|
|
|
<IndexRedirect to='/getting-started' /> |
|
|
|
<Route path='getting-started' component={GettingStarted} /> |
|
|
|
<Route path='timelines/home' component={HomeTimeline} /> |
|
|
|
<Route path='timelines/public' component={PublicTimeline} /> |
|
|
|
<Route path='timelines/public/local' component={CommunityTimeline} /> |
|
|
|
<Route path='timelines/tag/:id' component={HashtagTimeline} /> |
|
|
|
|
|
|
|
<Route path='notifications' component={Notifications} /> |
|
|
|
<Route path='favourites' component={FavouritedStatuses} /> |
|
|
|
|
|
|
|
<Route path='statuses/new' component={Compose} /> |
|
|
|
<Route path='statuses/:statusId' component={Status} /> |
|
|
|
<Route path='statuses/:statusId/reblogs' component={Reblogs} /> |
|
|
|