diff options
author | Thibaut Girka <thib@sitedethib.com> | 2019-08-28 16:28:55 +0200 |
---|---|---|
committer | ThibG <thib@sitedethib.com> | 2019-08-29 12:02:20 +0200 |
commit | 956c1cf82a4fa018311ad985336c46c05e799ee4 (patch) | |
tree | ba07b412415d7159fe7b928dc70738bee11188fb /app/javascript/flavours | |
parent | 3282bbe45413e790a5c77b2dda5b28b392a57c9f (diff) |
Refactor the Columns Area code to be closer to upstream
Diffstat (limited to 'app/javascript/flavours')
-rw-r--r-- | app/javascript/flavours/glitch/features/ui/index.js | 168 |
1 files changed, 107 insertions, 61 deletions
diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js index e072c22ec..be1a5343a 100644 --- a/app/javascript/flavours/glitch/features/ui/index.js +++ b/app/javascript/flavours/glitch/features/ui/index.js @@ -104,10 +104,108 @@ const keyMap = { 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 @withRouter -export default class UI extends React.Component { +class UI extends React.Component { static propTypes = { dispatch: PropTypes.func.isRequired, @@ -129,7 +227,6 @@ export default class UI extends React.Component { }; state = { - width: window.innerWidth, draggingOver: false, }; @@ -144,14 +241,10 @@ export default class UI extends React.Component { } } - handleResize = debounce(() => { + handleLayoutChange = () => { // The cached heights are no longer accurate, invalidate this.props.dispatch(clearHeight()); - - this.setState({ width: window.innerWidth }); - }, 500, { - trailing: true, - }); + } handleDragEnter = (e) => { e.preventDefault(); @@ -246,7 +339,6 @@ export default class UI extends React.Component { } window.addEventListener('beforeunload', this.handleBeforeUnload, false); - window.addEventListener('resize', this.handleResize, { passive: true }); document.addEventListener('dragenter', this.handleDragEnter, false); document.addEventListener('dragover', this.handleDragOver, false); document.addEventListener('drop', this.handleDrop, false); @@ -271,9 +363,6 @@ export default class UI extends React.Component { } componentDidUpdate (prevProps) { - if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) { - this.columnsAreaNode.handleChildrenContentChange(); - } if (this.props.unreadNotifications != prevProps.unreadNotifications || this.props.showFaviconBadge != prevProps.showFaviconBadge) { if (this.favicon) { @@ -288,7 +377,6 @@ export default class UI extends React.Component { } window.removeEventListener('beforeunload', this.handleBeforeUnload); - window.removeEventListener('resize', this.handleResize); document.removeEventListener('dragenter', this.handleDragEnter); document.removeEventListener('dragover', this.handleDragOver); document.removeEventListener('drop', this.handleDrop); @@ -300,10 +388,6 @@ export default class UI extends React.Component { this.node = c; } - setColumnsAreaRef = c => { - this.columnsAreaNode = c.getWrappedInstance(); - } - handleHotkeyNew = e => { e.preventDefault(); @@ -417,10 +501,8 @@ export default class UI extends React.Component { } render () { - const { width, draggingOver } = this.state; - const { children, layout, isWide, navbarUnder, dropdownMenuIsOpen } = this.props; - const singleColumn = isMobile(width, layout); - const redirect = singleColumn ? <Redirect from='/' to='/timelines/home' exact /> : <Redirect from='/' to='/getting-started' exact />; + const { draggingOver } = this.state; + const { children, layout, isWide, navbarUnder, location, dropdownMenuIsOpen } = this.props; const columnsClass = layout => { switch (layout) { @@ -464,45 +546,9 @@ export default class UI extends React.Component { return ( <HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused> <div className={className} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? 'none' : null }}> - <ColumnsAreaContainer ref={this.setColumnsAreaRef} 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> + <SwitchingColumnsArea location={location} layout={layout} navbarUnder={navbarUnder} onLayoutChange={this.handleLayoutChange}> + {children} + </SwitchingColumnsArea> <NotificationsContainer /> <LoadingBarContainer className='loading-bar' /> |