Refactor the Columns Area code to be closer to upstream
parent
5de49ea272
commit
ed4dbca6bc
|
@ -104,10 +104,108 @@ const keyMap = {
|
||||||
toggleSensitive: 'h',
|
toggleSensitive: 'h',
|
||||||
};
|
};
|
||||||
|
|
||||||
@connect(mapStateToProps)
|
class SwitchingColumnsArea extends React.PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
layout: PropTypes.string,
|
||||||
|
location: PropTypes.object,
|
||||||
|
navbarUnder: PropTypes.bool,
|
||||||
|
onLayoutChange: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
state = {
|
||||||
|
mobile: isMobile(window.innerWidth, this.props.layout),
|
||||||
|
};
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (nextProps.layout !== this.props.layout) {
|
||||||
|
this.setState({ mobile: isMobile(window.innerWidth, nextProps.layout) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount () {
|
||||||
|
window.addEventListener('resize', this.handleResize, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate (prevProps) {
|
||||||
|
if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) {
|
||||||
|
this.node.handleChildrenContentChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
window.removeEventListener('resize', this.handleResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleResize = debounce(() => {
|
||||||
|
// The cached heights are no longer accurate, invalidate
|
||||||
|
this.props.onLayoutChange();
|
||||||
|
|
||||||
|
this.setState({ mobile: isMobile(window.innerWidth, this.props.layout) });
|
||||||
|
}, 500, {
|
||||||
|
trailing: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
setRef = c => {
|
||||||
|
this.node = c.getWrappedInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { children, navbarUnder } = this.props;
|
||||||
|
const singleColumn = this.state.mobile;
|
||||||
|
const redirect = singleColumn ? <Redirect from='/' to='/timelines/home' exact /> : <Redirect from='/' to='/getting-started' exact />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn} navbarUnder={navbarUnder}>
|
||||||
|
<WrappedSwitch>
|
||||||
|
{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} />
|
||||||
|
<WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} />
|
||||||
|
<WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} />
|
||||||
|
<WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} />
|
||||||
|
<WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} />
|
||||||
|
<WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} />
|
||||||
|
|
||||||
|
<WrappedRoute path='/notifications' component={Notifications} content={children} />
|
||||||
|
<WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} />
|
||||||
|
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
||||||
|
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
||||||
|
|
||||||
|
<WrappedRoute path='/search' component={Search} content={children} />
|
||||||
|
|
||||||
|
<WrappedRoute path='/statuses/new' component={Compose} content={children} />
|
||||||
|
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />
|
||||||
|
<WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} />
|
||||||
|
<WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />
|
||||||
|
|
||||||
|
<WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} />
|
||||||
|
<WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
||||||
|
<WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} />
|
||||||
|
<WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} />
|
||||||
|
<WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} />
|
||||||
|
|
||||||
|
<WrappedRoute path='/follow_requests' component={FollowRequests} content={children} />
|
||||||
|
<WrappedRoute path='/blocks' component={Blocks} content={children} />
|
||||||
|
<WrappedRoute path='/domain_blocks' component={DomainBlocks} content={children} />
|
||||||
|
<WrappedRoute path='/mutes' component={Mutes} content={children} />
|
||||||
|
<WrappedRoute path='/lists' component={Lists} content={children} />
|
||||||
|
<WrappedRoute path='/getting-started-misc' component={GettingStartedMisc} content={children} />
|
||||||
|
|
||||||
|
<WrappedRoute component={GenericNotFound} content={children} />
|
||||||
|
</WrappedSwitch>
|
||||||
|
</ColumnsAreaContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default @connect(mapStateToProps)
|
||||||
@injectIntl
|
@injectIntl
|
||||||
@withRouter
|
@withRouter
|
||||||
export default class UI extends React.Component {
|
class UI extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
@ -129,7 +227,6 @@ export default class UI extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
width: window.innerWidth,
|
|
||||||
draggingOver: false,
|
draggingOver: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,14 +241,10 @@ export default class UI extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
handleLayoutChange = () => {
|
||||||
// The cached heights are no longer accurate, invalidate
|
// The cached heights are no longer accurate, invalidate
|
||||||
this.props.dispatch(clearHeight());
|
this.props.dispatch(clearHeight());
|
||||||
|
}
|
||||||
this.setState({ width: window.innerWidth });
|
|
||||||
}, 500, {
|
|
||||||
trailing: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
handleDragEnter = (e) => {
|
handleDragEnter = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -246,7 +339,6 @@ export default class UI extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('beforeunload', this.handleBeforeUnload, false);
|
window.addEventListener('beforeunload', this.handleBeforeUnload, false);
|
||||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
|
||||||
document.addEventListener('dragenter', this.handleDragEnter, false);
|
document.addEventListener('dragenter', this.handleDragEnter, false);
|
||||||
document.addEventListener('dragover', this.handleDragOver, false);
|
document.addEventListener('dragover', this.handleDragOver, false);
|
||||||
document.addEventListener('drop', this.handleDrop, false);
|
document.addEventListener('drop', this.handleDrop, false);
|
||||||
|
@ -271,9 +363,6 @@ export default class UI extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) {
|
|
||||||
this.columnsAreaNode.handleChildrenContentChange();
|
|
||||||
}
|
|
||||||
if (this.props.unreadNotifications != prevProps.unreadNotifications ||
|
if (this.props.unreadNotifications != prevProps.unreadNotifications ||
|
||||||
this.props.showFaviconBadge != prevProps.showFaviconBadge) {
|
this.props.showFaviconBadge != prevProps.showFaviconBadge) {
|
||||||
if (this.favicon) {
|
if (this.favicon) {
|
||||||
|
@ -288,7 +377,6 @@ export default class UI extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
window.removeEventListener('beforeunload', this.handleBeforeUnload);
|
||||||
window.removeEventListener('resize', this.handleResize);
|
|
||||||
document.removeEventListener('dragenter', this.handleDragEnter);
|
document.removeEventListener('dragenter', this.handleDragEnter);
|
||||||
document.removeEventListener('dragover', this.handleDragOver);
|
document.removeEventListener('dragover', this.handleDragOver);
|
||||||
document.removeEventListener('drop', this.handleDrop);
|
document.removeEventListener('drop', this.handleDrop);
|
||||||
|
@ -300,10 +388,6 @@ export default class UI extends React.Component {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
setColumnsAreaRef = c => {
|
|
||||||
this.columnsAreaNode = c.getWrappedInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleHotkeyNew = e => {
|
handleHotkeyNew = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -417,10 +501,8 @@ export default class UI extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { width, draggingOver } = this.state;
|
const { draggingOver } = this.state;
|
||||||
const { children, layout, isWide, navbarUnder, dropdownMenuIsOpen } = this.props;
|
const { children, layout, isWide, navbarUnder, location, dropdownMenuIsOpen } = this.props;
|
||||||
const singleColumn = isMobile(width, layout);
|
|
||||||
const redirect = singleColumn ? <Redirect from='/' to='/timelines/home' exact /> : <Redirect from='/' to='/getting-started' exact />;
|
|
||||||
|
|
||||||
const columnsClass = layout => {
|
const columnsClass = layout => {
|
||||||
switch (layout) {
|
switch (layout) {
|
||||||
|
@ -464,45 +546,9 @@ export default class UI extends React.Component {
|
||||||
return (
|
return (
|
||||||
<HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused>
|
<HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused>
|
||||||
<div className={className} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? 'none' : null }}>
|
<div className={className} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? 'none' : null }}>
|
||||||
<ColumnsAreaContainer ref={this.setColumnsAreaRef} singleColumn={singleColumn} navbarUnder={navbarUnder}>
|
<SwitchingColumnsArea location={location} layout={layout} navbarUnder={navbarUnder} onLayoutChange={this.handleLayoutChange}>
|
||||||
<WrappedSwitch>
|
{children}
|
||||||
{redirect}
|
</SwitchingColumnsArea>
|
||||||
<WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
|
|
||||||
<WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
|
|
||||||
<WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/notifications' component={Notifications} content={children} />
|
|
||||||
<WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} />
|
|
||||||
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
|
||||||
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
|
||||||
|
|
||||||
<WrappedRoute path='/search' component={Search} content={children} />
|
|
||||||
|
|
||||||
<WrappedRoute path='/statuses/new' component={Compose} content={children} />
|
|
||||||
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />
|
|
||||||
<WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} />
|
|
||||||
<WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />
|
|
||||||
|
|
||||||
<WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} />
|
|
||||||
<WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
|
||||||
<WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} />
|
|
||||||
<WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} />
|
|
||||||
<WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} />
|
|
||||||
|
|
||||||
<WrappedRoute path='/follow_requests' component={FollowRequests} content={children} />
|
|
||||||
<WrappedRoute path='/blocks' component={Blocks} content={children} />
|
|
||||||
<WrappedRoute path='/domain_blocks' component={DomainBlocks} content={children} />
|
|
||||||
<WrappedRoute path='/mutes' component={Mutes} content={children} />
|
|
||||||
<WrappedRoute path='/lists' component={Lists} content={children} />
|
|
||||||
<WrappedRoute path='/getting-started-misc' component={GettingStartedMisc} content={children} />
|
|
||||||
|
|
||||||
<WrappedRoute component={GenericNotFound} content={children} />
|
|
||||||
</WrappedSwitch>
|
|
||||||
</ColumnsAreaContainer>
|
|
||||||
|
|
||||||
<NotificationsContainer />
|
<NotificationsContainer />
|
||||||
<LoadingBarContainer className='loading-bar' />
|
<LoadingBarContainer className='loading-bar' />
|
||||||
|
|
Loading…
Reference in New Issue