From ec22cc8afaef9381ba0452c1b3a92680e877c882 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 19 Oct 2021 15:13:04 -0500 Subject: [PATCH 1/3] AccountTimeline: add SubNavigation --- app/soapbox/components/sub_navigation.js | 4 +- .../components/column_settings.js | 59 +++++++++++++------ .../features/account_timeline/index.js | 11 +--- app/styles/components/account-header.scss | 6 ++ app/styles/components/columns.scss | 10 ++++ app/styles/components/tabs-bar.scss | 2 +- app/styles/ui.scss | 3 +- 7 files changed, 64 insertions(+), 31 deletions(-) diff --git a/app/soapbox/components/sub_navigation.js b/app/soapbox/components/sub_navigation.js index abaceedfa..063448b5c 100644 --- a/app/soapbox/components/sub_navigation.js +++ b/app/soapbox/components/sub_navigation.js @@ -73,9 +73,9 @@ class SubNavigation extends React.PureComponent { handleScroll = throttle(() => { if (this.node) { - const { top } = this.node.getBoundingClientRect(); + const { offsetTop } = this.node; - if (top <= 50) { + if (offsetTop > 0) { this.setState({ scrolled: true }); } else { this.setState({ scrolled: false }); diff --git a/app/soapbox/features/account_timeline/components/column_settings.js b/app/soapbox/features/account_timeline/components/column_settings.js index 7836c01f0..130cb47db 100644 --- a/app/soapbox/features/account_timeline/components/column_settings.js +++ b/app/soapbox/features/account_timeline/components/column_settings.js @@ -1,38 +1,59 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { injectIntl, FormattedMessage } from 'react-intl'; +import { injectIntl, defineMessages, FormattedMessage } from 'react-intl'; +import IconButton from 'soapbox/components/icon_button'; import SettingToggle from '../../notifications/components/setting_toggle'; +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); + export default @injectIntl class ColumnSettings extends React.PureComponent { static propTypes = { + intl: PropTypes.object.isRequired, settings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, }; render() { - const { settings, onChange } = this.props; + const { intl, settings, onChange, onClose } = this.props; return ( -
-
- } - /> - } - /> +
+
+

+ +

+
+ +
+
+ +
+
+ +
+ +
+ } + /> + } + /> +
); diff --git a/app/soapbox/features/account_timeline/index.js b/app/soapbox/features/account_timeline/index.js index 003ab8dda..b55decbba 100644 --- a/app/soapbox/features/account_timeline/index.js +++ b/app/soapbox/features/account_timeline/index.js @@ -9,6 +9,7 @@ import StatusList from '../../components/status_list'; import LoadingIndicator from '../../components/loading_indicator'; import Column from '../ui/components/column'; import ColumnSettingsContainer from './containers/column_settings_container'; +import SubNavigation from 'soapbox/components/sub_navigation'; import { OrderedSet as ImmutableOrderedSet } from 'immutable'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { FormattedMessage } from 'react-intl'; @@ -19,7 +20,6 @@ import { fetchPatronAccount } from '../../actions/patron'; import { getSoapboxConfig } from 'soapbox/actions/soapbox'; import { getSettings } from 'soapbox/actions/settings'; import { makeGetStatusIds, findAccountByUsername } from 'soapbox/selectors'; -import classNames from 'classnames'; const makeMapStateToProps = () => { const getStatusIds = makeGetStatusIds(); @@ -146,7 +146,6 @@ class AccountTimeline extends ImmutablePureComponent { render() { const { statusIds, featuredStatusIds, isLoading, hasMore, isBlocked, isAccount, accountId, unavailable, accountUsername } = this.props; - const { collapsed, animating } = this.state; if (!isAccount && accountId !== -1) { return ( @@ -176,7 +175,8 @@ class AccountTimeline extends ImmutablePureComponent { } return ( - + +
@@ -193,11 +193,6 @@ class AccountTimeline extends ImmutablePureComponent {
-
-
- {(!collapsed || animating) && } -
-
Date: Tue, 19 Oct 2021 15:16:47 -0500 Subject: [PATCH 2/3] AccountTimeline: don't display column settings for now --- app/soapbox/features/account_timeline/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/soapbox/features/account_timeline/index.js b/app/soapbox/features/account_timeline/index.js index b55decbba..4d4d916ea 100644 --- a/app/soapbox/features/account_timeline/index.js +++ b/app/soapbox/features/account_timeline/index.js @@ -8,7 +8,7 @@ import Icon from 'soapbox/components/icon'; import StatusList from '../../components/status_list'; import LoadingIndicator from '../../components/loading_indicator'; import Column from '../ui/components/column'; -import ColumnSettingsContainer from './containers/column_settings_container'; +// import ColumnSettingsContainer from './containers/column_settings_container'; import SubNavigation from 'soapbox/components/sub_navigation'; import { OrderedSet as ImmutableOrderedSet } from 'immutable'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -176,7 +176,7 @@ class AccountTimeline extends ImmutablePureComponent { return ( - +
From 0e8ed14ffec0a0157c711cc574e375c51b391928 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 19 Oct 2021 16:09:22 -0500 Subject: [PATCH 3/3] TabsBar: add notifications back for desktop UI --- .../features/ui/components/tabs_bar.js | 60 ++++++++++++++++--- app/styles/components/icon.scss | 8 +-- app/styles/components/tabs-bar.scss | 51 +++++++--------- 3 files changed, 79 insertions(+), 40 deletions(-) diff --git a/app/soapbox/features/ui/components/tabs_bar.js b/app/soapbox/features/ui/components/tabs_bar.js index 8a7dbaf18..d82356fd0 100644 --- a/app/soapbox/features/ui/components/tabs_bar.js +++ b/app/soapbox/features/ui/components/tabs_bar.js @@ -1,10 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { Link, withRouter } from 'react-router-dom'; +import { Link, NavLink, withRouter } from 'react-router-dom'; import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import { connect } from 'react-redux'; import classNames from 'classnames'; +import IconWithCounter from 'soapbox/components/icon_with_counter'; import SearchContainer from 'soapbox/features/compose/containers/search_container'; import Avatar from '../../../components/avatar'; import Icon from 'soapbox/components/icon'; @@ -13,6 +14,8 @@ import { openModal } from '../../../actions/modal'; import { openSidebar } from '../../../actions/sidebar'; import ThemeToggle from '../../ui/components/theme_toggle_container'; import { getSoapboxConfig } from 'soapbox/actions/soapbox'; +import { isStaff } from 'soapbox/utils/accounts'; +import { getFeatures } from 'soapbox/utils/features'; const messages = defineMessages({ post: { id: 'tabs_bar.post', defaultMessage: 'Post' }, @@ -27,6 +30,10 @@ class TabsBar extends React.PureComponent { onOpenSidebar: PropTypes.func.isRequired, logo: PropTypes.string, account: ImmutablePropTypes.map, + features: PropTypes.object.isRequired, + dashboardCount: PropTypes.number, + notificationCount: PropTypes.number, + chatsCount: PropTypes.number, } state = { @@ -47,7 +54,7 @@ class TabsBar extends React.PureComponent { } render() { - const { account, logo, onOpenCompose, onOpenSidebar, intl } = this.props; + const { intl, account, logo, onOpenCompose, onOpenSidebar, features, dashboardCount, notificationCount, chatsCount } = this.props; const { collapsed } = this.state; const classes = classNames('tabs-bar', { @@ -75,8 +82,42 @@ class TabsBar extends React.PureComponent {
- {account && + {account ? ( <> + + 0, + })} + count={notificationCount} + /> + + + + {features.chats && ( + + + + + )} + + {isStaff(account) && ( + + + + + )} +
@@ -87,9 +128,7 @@ class TabsBar extends React.PureComponent { {intl.formatMessage(messages.post)} - } - { - !account && + ) : (
@@ -98,7 +137,7 @@ class TabsBar extends React.PureComponent {
- } + )}
@@ -109,10 +148,17 @@ class TabsBar extends React.PureComponent { const mapStateToProps = state => { const me = state.get('me'); + const reportsCount = state.getIn(['admin', 'openReports']).count(); + const approvalCount = state.getIn(['admin', 'awaitingApproval']).count(); + const instance = state.get('instance'); return { account: state.getIn(['accounts', me]), logo: getSoapboxConfig(state).get('logo'), + features: getFeatures(instance), + notificationCount: state.getIn(['notifications', 'unread']), + chatsCount: state.get('chats').reduce((acc, curr) => acc + Math.min(curr.get('unread', 0), 1), 0), + dashboardCount: reportsCount + approvalCount, }; }; diff --git a/app/styles/components/icon.scss b/app/styles/components/icon.scss index 40b55cdda..3514ab03a 100644 --- a/app/styles/components/icon.scss +++ b/app/styles/components/icon.scss @@ -25,14 +25,14 @@ svg.icon-tabler-bell, svg.icon-tabler-messages { path:nth-child(2) { - fill: var(--primary-text-color); + fill: currentColor; } } svg.icon-tabler-users { circle, circle + path { - fill: var(--primary-text-color); + fill: currentColor; } } @@ -40,8 +40,8 @@ stroke: var(--background-color); rect { - fill: var(--primary-text-color); - stroke: var(--primary-text-color); + fill: currentColor; + stroke: currentColor; } } } diff --git a/app/styles/components/tabs-bar.scss b/app/styles/components/tabs-bar.scss index 90ff85ddf..0a14c211a 100644 --- a/app/styles/components/tabs-bar.scss +++ b/app/styles/components/tabs-bar.scss @@ -142,11 +142,13 @@ } .theme-toggle { - @media screen and (max-width: $nav-breakpoint-3) { display: none; } + margin-left: 20px; + + @media screen and (max-width: $nav-breakpoint-3) { + display: none; + } .setting-toggle { - margin-left: 10px; - .react-toggle-track { background-color: var(--foreground-color); } @@ -168,7 +170,6 @@ .tabs-bar__link { display: flex; flex: 1 1 auto; - margin: 0 20px 0 0; color: #fff; text-decoration: none; position: relative; @@ -183,14 +184,18 @@ width: 36px; margin: 4px 4px 0 0; justify-content: center; - - & > span { display: none; } + display: none; } > span { font-size: 15px; line-height: 50px; margin-left: 4px; + display: none; + } + + & + & { + margin-left: 20px; } &--search { @@ -199,28 +204,12 @@ } } - i.fa { - font-size: 14px; - transform: translate(-1px, -1px); - transition: 0.1s; + .svg-icon { + width: 22px; + height: 22px; - @media screen and (max-width: 895px) { - font-size: 20px; - } - - &.fa-home { - font-size: 18px; - transform: translate(-1px, -2px); - - @media screen and (max-width: 895px) { - font-size: 26px; - } - } - } - - .icon-with-counter__counter { - @media screen and (min-width: 896px) { - left: 5px; + svg.icon-tabler { + stroke-width: 1.5px; } } @@ -244,8 +233,8 @@ height: 15px; border-radius: 999px; z-index: -1; - width: calc(100% + 20px); - margin-left: -12px; + width: calc(100% + 12px); + margin-left: -9px; @media screen and (max-width: 895px) { height: 0; @@ -339,3 +328,7 @@ } } } + +.tabs-bar__link + .tabs-bar__profile { + margin-left: 20px; +}