diff options
author | Starfall <us@starfall.systems> | 2022-11-10 08:50:11 -0600 |
---|---|---|
committer | Starfall <us@starfall.systems> | 2022-11-10 08:50:11 -0600 |
commit | 67d1a0476d77e2ed0ca15dd2981c54c2b90b0742 (patch) | |
tree | 152f8c13a341d76738e8e2c09b24711936e6af68 /app/javascript/flavours/glitch/features/ui/index.js | |
parent | b581e6b6d4a5ba9ed4ae17427b7f2d5d158be4e5 (diff) | |
parent | ee7e49d1b1323618e16026bc8db8ab7f9459cc2d (diff) |
Merge remote-tracking branch 'glitch/main'
- Remove Helm charts - Lots of conflicts with our removal of recommended settings and custom icons
Diffstat (limited to 'app/javascript/flavours/glitch/features/ui/index.js')
-rw-r--r-- | app/javascript/flavours/glitch/features/ui/index.js | 187 |
1 files changed, 110 insertions, 77 deletions
diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js index 2be6d9478..3d385eee2 100644 --- a/app/javascript/flavours/glitch/features/ui/index.js +++ b/app/javascript/flavours/glitch/features/ui/index.js @@ -4,16 +4,18 @@ import PropTypes from 'prop-types'; import LoadingBarContainer from './containers/loading_bar_container'; import ModalContainer from './containers/modal_container'; import { connect } from 'react-redux'; -import { Redirect, withRouter } from 'react-router-dom'; -import { isMobile } from 'flavours/glitch/util/is_mobile'; +import { Redirect, Route, withRouter } from 'react-router-dom'; +import { layoutFromWindow } from 'flavours/glitch/is_mobile'; import { debounce } from 'lodash'; import { uploadCompose, resetCompose, changeComposeSpoilerness } from 'flavours/glitch/actions/compose'; import { expandHomeTimeline } from 'flavours/glitch/actions/timelines'; import { expandNotifications, notificationsSetVisibility } from 'flavours/glitch/actions/notifications'; -import { fetchRules } from 'flavours/glitch/actions/rules'; +import { fetchServer } from 'flavours/glitch/actions/server'; import { clearHeight } from 'flavours/glitch/actions/height_cache'; +import { changeLayout } from 'flavours/glitch/actions/app'; import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'flavours/glitch/actions/markers'; -import { WrappedSwitch, WrappedRoute } from 'flavours/glitch/util/react_router_helpers'; +import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers'; +import BundleColumnError from './components/bundle_column_error'; import UploadArea from './components/upload_area'; import PermaLink from 'flavours/glitch/components/permalink'; import ColumnsAreaContainer from './containers/columns_area_container'; @@ -38,7 +40,6 @@ import { HashtagTimeline, Notifications, FollowRequests, - GenericNotFound, FavouritedStatuses, BookmarkedStatuses, ListTimeline, @@ -47,15 +48,19 @@ import { Mutes, PinnedStatuses, Lists, - Search, GettingStartedMisc, Directory, + Explore, FollowRecommendations, -} from 'flavours/glitch/util/async-components'; + About, + PrivacyPolicy, +} from './util/async-components'; import { HotKeys } from 'react-hotkeys'; -import { me } from 'flavours/glitch/util/initial_state'; +import initialState, { me, owner, singleUserMode, showTrends } from '../../initial_state'; import { closeOnboarding, INTRODUCTION_VERSION } from 'flavours/glitch/actions/onboarding'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { Helmet } from 'react-helmet'; +import Header from './components/header'; // Dummy import, to make sure that <Status /> ends up in the application bundle. // Without this it ends up in ~8 very commonly used bundles. @@ -66,10 +71,12 @@ const messages = defineMessages({ }); const mapStateToProps = state => ({ + layout: state.getIn(['meta', 'layout']), hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, - layout: state.getIn(['local_settings', 'layout']), + layout: state.getIn(['meta', 'layout']), + layout_local_setting: state.getIn(['local_settings', 'layout']), isWide: state.getIn(['local_settings', 'stretch']), navbarUnder: state.getIn(['local_settings', 'navbar_under']), dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null, @@ -118,28 +125,19 @@ const keyMap = { class SwitchingColumnsArea extends React.PureComponent { + static contextTypes = { + identity: PropTypes.object, + }; + 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), + mobile: PropTypes.bool, }; - componentWillReceiveProps (nextProps) { - if (nextProps.layout !== this.props.layout) { - this.setState({ mobile: isMobile(window.innerWidth, nextProps.layout) }); - } - } - componentWillMount () { - window.addEventListener('resize', this.handleResize, { passive: true }); - - if (this.state.mobile) { + if (this.props.mobile) { document.body.classList.toggle('layout-single-column', true); document.body.classList.toggle('layout-multiple-columns', false); } else { @@ -148,57 +146,52 @@ class SwitchingColumnsArea extends React.PureComponent { } } - componentDidUpdate (prevProps, prevState) { + componentDidUpdate (prevProps) { if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) { this.node.handleChildrenContentChange(); } - if (prevState.mobile !== this.state.mobile) { - document.body.classList.toggle('layout-single-column', this.state.mobile); - document.body.classList.toggle('layout-multiple-columns', !this.state.mobile); - } - } - - componentWillUnmount () { - window.removeEventListener('resize', this.handleResize); - } - - handleLayoutChange = debounce(() => { - // The cached heights are no longer accurate, invalidate - this.props.onLayoutChange(); - }, 500, { - trailing: true, - }) - - handleResize = () => { - const mobile = isMobile(window.innerWidth, this.props.layout); - - if (mobile !== this.state.mobile) { - this.handleLayoutChange.cancel(); - this.props.onLayoutChange(); - this.setState({ mobile }); - } else { - this.handleLayoutChange(); + if (prevProps.mobile !== this.props.mobile) { + document.body.classList.toggle('layout-single-column', this.props.mobile); + document.body.classList.toggle('layout-multiple-columns', !this.props.mobile); } } setRef = c => { if (c) { - this.node = c.getWrappedInstance(); + this.node = c; } } render () { - const { children, navbarUnder } = this.props; - const singleColumn = this.state.mobile; - const redirect = singleColumn ? <Redirect from='/' to='/home' exact /> : <Redirect from='/' to='/getting-started' exact />; + const { children, mobile, navbarUnder } = this.props; + const { signedIn } = this.context.identity; + + let redirect; + + if (signedIn) { + if (mobile) { + redirect = <Redirect from='/' to='/home' exact />; + } else { + redirect = <Redirect from='/' to='/getting-started' exact />; + } + } else if (singleUserMode && owner && initialState?.accounts[owner]) { + redirect = <Redirect from='/' to={`/@${initialState.accounts[owner].username}`} exact />; + } else if (showTrends) { + redirect = <Redirect from='/' to='/explore' exact />; + } else { + redirect = <Redirect from='/' to='/about' exact />; + } return ( - <ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn} navbarUnder={navbarUnder}> + <ColumnsAreaContainer ref={this.setRef} singleColumn={mobile} navbarUnder={navbarUnder}> <WrappedSwitch> {redirect} + <WrappedRoute path='/getting-started' component={GettingStarted} content={children} /> <WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} /> + <WrappedRoute path='/about' component={About} content={children} /> + <WrappedRoute path='/privacy-policy' component={PrivacyPolicy} content={children} /> <WrappedRoute path={['/home', '/timelines/home']} component={HomeTimeline} content={children} /> <WrappedRoute path={['/public', '/timelines/public']} exact component={PublicTimeline} content={children} /> @@ -213,14 +206,15 @@ class SwitchingColumnsArea extends React.PureComponent { <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} /> <WrappedRoute path='/start' component={FollowRecommendations} content={children} /> - <WrappedRoute path='/search' component={Search} content={children} /> <WrappedRoute path='/directory' component={Directory} content={children} /> + <WrappedRoute path={['/explore', '/search']} component={Explore} content={children} /> <WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} /> <WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} /> + <WrappedRoute path='/@:acct/tagged/:tagged?' exact component={AccountTimeline} content={children} /> <WrappedRoute path={['/@:acct/with_replies', '/accounts/:id/with_replies']} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} /> - <WrappedRoute path={['/@:acct/followers', '/accounts/:id/followers']} component={Followers} content={children} /> - <WrappedRoute path={['/@:acct/following', '/accounts/:id/following']} component={Following} content={children} /> + <WrappedRoute path={['/accounts/:id/followers', '/users/:acct/followers', '/@:acct/followers']} component={Followers} content={children} /> + <WrappedRoute path={['/accounts/:id/following', '/users/:acct/following', '/@:acct/following']} component={Following} content={children} /> <WrappedRoute path={['/@:acct/media', '/accounts/:id/media']} component={AccountGallery} content={children} /> <WrappedRoute path='/@:acct/:statusId' exact component={Status} content={children} /> <WrappedRoute path='/@:acct/:statusId/reblogs' component={Reblogs} content={children} /> @@ -240,7 +234,7 @@ class SwitchingColumnsArea extends React.PureComponent { <WrappedRoute path='/lists' component={Lists} content={children} /> <WrappedRoute path='/getting-started-misc' component={GettingStartedMisc} content={children} /> - <WrappedRoute component={GenericNotFound} content={children} /> + <Route component={BundleColumnError} /> </WrappedSwitch> </ColumnsAreaContainer> ); @@ -253,10 +247,14 @@ export default @connect(mapStateToProps) @withRouter class UI extends React.Component { + static contextTypes = { + identity: PropTypes.object.isRequired, + }; + static propTypes = { dispatch: PropTypes.func.isRequired, children: PropTypes.node, - layout: PropTypes.string, + layout_local_setting: PropTypes.string, isWide: PropTypes.bool, systemFontUi: PropTypes.bool, navbarUnder: PropTypes.bool, @@ -272,6 +270,7 @@ class UI extends React.Component { unreadNotifications: PropTypes.number, showFaviconBadge: PropTypes.bool, moved: PropTypes.map, + layout: PropTypes.string.isRequired, firstLaunch: PropTypes.bool, username: PropTypes.string, }; @@ -293,11 +292,6 @@ class UI extends React.Component { } } - handleLayoutChange = () => { - // The cached heights are no longer accurate, invalidate - this.props.dispatch(clearHeight()); - } - handleDragEnter = (e) => { e.preventDefault(); @@ -378,8 +372,29 @@ class UI extends React.Component { } } - componentWillMount () { + handleLayoutChange = debounce(() => { + this.props.dispatch(clearHeight()); // The cached heights are no longer accurate, invalidate + }, 500, { + trailing: true, + }); + + handleResize = () => { + const layout = layoutFromWindow(this.props.layout_local_setting); + + if (layout !== this.props.layout) { + this.handleLayoutChange.cancel(); + this.props.dispatch(changeLayout(layout)); + } else { + this.handleLayoutChange(); + } + } + + componentDidMount () { + const { signedIn } = this.context.identity; + 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); @@ -393,19 +408,19 @@ class UI extends React.Component { this.favicon = new Favico({ animation:"none" }); // On first launch, redirect to the follow recommendations page - if (this.props.firstLaunch) { + if (signedIn && this.props.firstLaunch) { this.context.router.history.replace('/start'); this.props.dispatch(closeOnboarding()); } - this.props.dispatch(fetchMarkers()); - this.props.dispatch(expandHomeTimeline()); - this.props.dispatch(expandNotifications()); + if (signedIn) { + this.props.dispatch(fetchMarkers()); + this.props.dispatch(expandHomeTimeline()); + this.props.dispatch(expandNotifications()); - setTimeout(() => this.props.dispatch(fetchRules()), 3000); - } + setTimeout(() => this.props.dispatch(fetchServer()), 3000); + } - componentDidMount () { this.hotkeys.__mousetrap__.stopCallback = (e, element) => { return ['TEXTAREA', 'SELECT', 'INPUT'].includes(element.tagName); }; @@ -427,6 +442,19 @@ class UI extends React.Component { } } + componentWillReceiveProps (nextProps) { + if (nextProps.layout_local_setting !== this.props.layout_local_setting) { + const layout = layoutFromWindow(nextProps.layout_local_setting); + + if (layout !== this.props.layout) { + this.handleLayoutChange.cancel(); + this.props.dispatch(changeLayout(layout)); + } else { + this.handleLayoutChange(); + } + } + } + componentDidUpdate (prevProps) { if (this.props.unreadNotifications != prevProps.unreadNotifications || this.props.showFaviconBadge != prevProps.showFaviconBadge) { @@ -446,6 +474,8 @@ 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); @@ -576,7 +606,7 @@ class UI extends React.Component { render () { const { draggingOver } = this.state; - const { children, layout, isWide, navbarUnder, location, dropdownMenuIsOpen, moved } = this.props; + const { children, isWide, navbarUnder, location, dropdownMenuIsOpen, layout, moved } = this.props; const columnsClass = layout => { switch (layout) { @@ -632,11 +662,14 @@ class UI extends React.Component { )}} /> </div>)} - <SwitchingColumnsArea location={location} layout={layout} navbarUnder={navbarUnder} onLayoutChange={this.handleLayoutChange}> + + <Header /> + + <SwitchingColumnsArea location={location} mobile={layout === 'mobile' || layout === 'single-column'} navbarUnder={navbarUnder}> {children} </SwitchingColumnsArea> - <PictureInPicture /> + {layout !== 'mobile' && <PictureInPicture />} <NotificationsContainer /> <LoadingBarContainer className='loading-bar' /> <ModalContainer /> |