diff options
author | Claire <claire.github-309c@sitedethib.com> | 2022-10-09 11:48:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-09 11:48:06 +0200 |
commit | 44486db912ac6064419680dbc3dcd3843a02a144 (patch) | |
tree | 6e14c1298ee1ecfb4ba962f5752bedf13efd4d17 /app/javascript/flavours/glitch/features/ui | |
parent | 30f4268f325921c13f786e7f8d52d744ea542ef2 (diff) | |
parent | 7ba5905416ab9e62e429fdd21bc353aaeb312375 (diff) |
Merge pull request #1859 from ClearlyClaire/glitch-soc/features/trends-tab
Port “Explore” tab to glitch-soc
Diffstat (limited to 'app/javascript/flavours/glitch/features/ui')
5 files changed, 62 insertions, 67 deletions
diff --git a/app/javascript/flavours/glitch/features/ui/components/columns_area.js b/app/javascript/flavours/glitch/features/ui/components/columns_area.js index bfb1ae405..048251fa6 100644 --- a/app/javascript/flavours/glitch/features/ui/components/columns_area.js +++ b/app/javascript/flavours/glitch/features/ui/components/columns_area.js @@ -49,7 +49,7 @@ const componentMap = { 'DIRECTORY': Directory, }; -const shouldHideFAB = path => path.match(/^\/statuses\/|^\/@[^/]+\/\d+|^\/publish|^\/search|^\/getting-started|^\/start/); +const shouldHideFAB = path => path.match(/^\/statuses\/|^\/@[^/]+\/\d+|^\/publish|^\/explore|^\/getting-started|^\/start/); const messages = defineMessages({ publish: { id: 'compose_form.publish', defaultMessage: 'Toot' }, diff --git a/app/javascript/flavours/glitch/features/ui/components/link_footer.js b/app/javascript/flavours/glitch/features/ui/components/link_footer.js index d91f9b8c4..67fa067f9 100644 --- a/app/javascript/flavours/glitch/features/ui/components/link_footer.js +++ b/app/javascript/flavours/glitch/features/ui/components/link_footer.js @@ -3,7 +3,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { Link } from 'react-router-dom'; -import { limitedFederationMode, version, repository, source_url } from 'flavours/glitch/util/initial_state'; +import { limitedFederationMode, version, repository, source_url, profile_directory as profileDirectory } from 'flavours/glitch/util/initial_state'; import { signOutLink, securityLink, privacyPolicyLink } from 'flavours/glitch/util/backend_links'; import { logOut } from 'flavours/glitch/util/log_out'; import { openModal } from 'flavours/glitch/actions/modal'; @@ -54,6 +54,7 @@ class LinkFooter extends React.PureComponent { {((this.context.identity.permissions & PERMISSION_INVITE_USERS) === PERMISSION_INVITE_USERS) && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>} {!!securityLink && <li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>} {!limitedFederationMode && <li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>} + {profileDirectory && <li><Link to='/directory'><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></Link> · </li>} <li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li> <li><a href={privacyPolicyLink} target='_blank'><FormattedMessage id='getting_started.privacy_policy' defaultMessage='Privacy Policy' /></a> · </li> <li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li> diff --git a/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js b/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js index 2dcd535ca..f4d649456 100644 --- a/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js +++ b/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js @@ -2,7 +2,7 @@ import React from 'react'; import { NavLink, withRouter } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import Icon from 'flavours/glitch/components/icon'; -import { profile_directory, showTrends } from 'flavours/glitch/util/initial_state'; +import { showTrends } from 'flavours/glitch/util/initial_state'; import { preferencesLink, relationshipsLink } from 'flavours/glitch/util/backend_links'; import NotificationsCounterIcon from './notifications_counter_icon'; import FollowRequestsNavLink from './follow_requests_nav_link'; @@ -14,11 +14,11 @@ const NavigationPanel = ({ onOpenSettings }) => ( <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 /> + { showTrends && <NavLink className='column-link column-link--transparent' to='/explore' data-preview-title-id='explore.title' data-preview-icon='hashtag'><Icon className='column-link__icon' id='hashtag' fixedWidth /><FormattedMessage id='explore.title' defaultMessage='Explore' /></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='/bookmarks'><Icon className='column-link__icon' id='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></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>} <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> <ListPanel /> diff --git a/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js b/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js index 55cc84f5e..0a7078a9c 100644 --- a/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js +++ b/app/javascript/flavours/glitch/features/ui/components/tabs_bar.js @@ -12,7 +12,7 @@ export const links = [ <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='/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 optional' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='search' ><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/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js index 2be6d9478..7b547fd5b 100644 --- a/app/javascript/flavours/glitch/features/ui/index.js +++ b/app/javascript/flavours/glitch/features/ui/index.js @@ -5,13 +5,14 @@ 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 { layoutFromWindow } from 'flavours/glitch/util/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 { 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 UploadArea from './components/upload_area'; @@ -47,9 +48,9 @@ import { Mutes, PinnedStatuses, Lists, - Search, GettingStartedMisc, Directory, + Explore, FollowRecommendations, } from 'flavours/glitch/util/async-components'; import { HotKeys } from 'react-hotkeys'; @@ -66,10 +67,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, @@ -120,26 +123,13 @@ class SwitchingColumnsArea extends React.PureComponent { static propTypes = { children: PropTypes.node, - layout: PropTypes.string, location: PropTypes.object, navbarUnder: PropTypes.bool, - onLayoutChange: PropTypes.func.isRequired, + mobile: PropTypes.bool, }; - 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 }); - - 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,37 +138,14 @@ 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); } } @@ -189,12 +156,11 @@ class SwitchingColumnsArea extends React.PureComponent { } 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 redirect = mobile ? <Redirect from='/' to='/home' exact /> : <Redirect from='/' to='/getting-started' 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} /> @@ -213,8 +179,8 @@ 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} /> @@ -256,7 +222,7 @@ class UI extends React.Component { 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 +238,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 +260,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 +340,27 @@ 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 () { 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); @@ -403,9 +384,7 @@ class UI extends React.Component { this.props.dispatch(expandNotifications()); setTimeout(() => this.props.dispatch(fetchRules()), 3000); - } - componentDidMount () { this.hotkeys.__mousetrap__.stopCallback = (e, element) => { return ['TEXTAREA', 'SELECT', 'INPUT'].includes(element.tagName); }; @@ -427,6 +406,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 +438,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 +570,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 +626,11 @@ class UI extends React.Component { )}} /> </div>)} - <SwitchingColumnsArea location={location} layout={layout} navbarUnder={navbarUnder} onLayoutChange={this.handleLayoutChange}> + <SwitchingColumnsArea location={location} mobile={layout === 'mobile' || layout === 'single-column'} navbarUnder={navbarUnder}> {children} </SwitchingColumnsArea> - <PictureInPicture /> + {layout !== 'mobile' && <PictureInPicture />} <NotificationsContainer /> <LoadingBarContainer className='loading-bar' /> <ModalContainer /> |