diff --git a/app/soapbox/components/sub_navigation.js b/app/soapbox/components/sub_navigation.js index 4ed61b69b..4e48f4dc5 100644 --- a/app/soapbox/components/sub_navigation.js +++ b/app/soapbox/components/sub_navigation.js @@ -1,15 +1,29 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; import { FormattedMessage } from 'react-intl'; import { throttle } from 'lodash'; import Icon from 'soapbox/components/icon'; +import IconButton from 'soapbox/components/icon_button'; import classNames from 'classnames'; import Helmet from 'soapbox/components/helmet'; +import { openModal } from 'soapbox/actions/modal'; -export default class SubNavigation extends React.PureComponent { +const mapDispatchToProps = (dispatch, { settings: Settings }) => { + return { + onOpenSettings() { + dispatch(openModal('COMPONENT', { component: Settings })); + }, + }; +}; + +export default @connect(undefined, mapDispatchToProps) +class SubNavigation extends React.PureComponent { static propTypes = { message: PropTypes.string, + settings: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), + onOpenSettings: PropTypes.func.isRequired, } static contextTypes = { @@ -62,12 +76,16 @@ export default class SubNavigation extends React.PureComponent { } }, 150, { trailing: true }); + handleOpenSettings = () => { + this.props.onOpenSettings(); + } + setRef = c => { this.node = c; } render() { - const { message } = this.props; + const { message, settings: Settings } = this.props; const { scrolled } = this.state; return ( @@ -87,6 +105,11 @@ export default class SubNavigation extends React.PureComponent { {message} )} + {Settings && ( +
+ +
+ )} ); diff --git a/app/soapbox/features/community_timeline/components/column_settings.js b/app/soapbox/features/community_timeline/components/column_settings.js index 60636ffee..1b00a9819 100644 --- a/app/soapbox/features/community_timeline/components/column_settings.js +++ b/app/soapbox/features/community_timeline/components/column_settings.js @@ -1,29 +1,46 @@ 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/community_timeline/index.js b/app/soapbox/features/community_timeline/index.js index ced92698a..0789253fc 100644 --- a/app/soapbox/features/community_timeline/index.js +++ b/app/soapbox/features/community_timeline/index.js @@ -4,6 +4,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import PropTypes from 'prop-types'; import StatusListContainer from '../ui/containers/status_list_container'; import Column from '../../components/column'; +import ColumnSettings from './containers/column_settings_container'; import { expandCommunityTimeline } from '../../actions/timelines'; import { connectCommunityStream } from '../../actions/streaming'; import { getSettings } from 'soapbox/actions/settings'; @@ -74,7 +75,7 @@ class CommunityTimeline extends React.PureComponent { return ( - + + +
+ ); + } + +} diff --git a/app/soapbox/features/ui/components/modal_root.js b/app/soapbox/features/ui/components/modal_root.js index 220d7f7d8..eed1278aa 100644 --- a/app/soapbox/features/ui/components/modal_root.js +++ b/app/soapbox/features/ui/components/modal_root.js @@ -23,6 +23,7 @@ import { ComposeModal, UnauthorizedModal, EditFederationModal, + ComponentModal, } from '../../../features/ui/util/async-components'; const MODAL_COMPONENTS = { @@ -43,6 +44,7 @@ const MODAL_COMPONENTS = { 'UNAUTHORIZED': UnauthorizedModal, 'CRYPTO_DONATE': CryptoDonateModal, 'EDIT_FEDERATION': EditFederationModal, + 'COMPONENT': ComponentModal, }; export default class ModalRoot extends React.PureComponent { diff --git a/app/soapbox/features/ui/util/async-components.js b/app/soapbox/features/ui/util/async-components.js index 5ec26591f..1e337f682 100644 --- a/app/soapbox/features/ui/util/async-components.js +++ b/app/soapbox/features/ui/util/async-components.js @@ -202,6 +202,10 @@ export function EmbedModal() { return import(/* webpackChunkName: "modals/embed_modal" */'../components/embed_modal'); } +export function ComponentModal() { + return import(/* webpackChunkName: "features/ui" */'../components/component_modal'); +} + export function ListEditor() { return import(/* webpackChunkName: "features/list_editor" */'../../list_editor'); } diff --git a/app/styles/components/columns.scss b/app/styles/components/columns.scss index f8eca7971..806b34f08 100644 --- a/app/styles/components/columns.scss +++ b/app/styles/components/columns.scss @@ -596,6 +596,45 @@ font-size: 20px; } +.component-modal { + @include standard-panel; + width: 400px; + max-width: calc(100% - 20px); +} + +.column-settings { + width: 100%; + + &__header { + border-bottom: 1px solid hsla(var(--primary-text-color_hsl), 0.2); + padding: 10px 20px; + display: flex; + align-items: center; + } + + &__title { + font-weight: bold; + color: var(--primary-text-color--faint); + } + + &__content { + padding: 10px 20px; + } + + &__close { + display: flex; + align-items: center; + justify-content: center; + margin-left: auto; + + .svg-icon { + width: 20px; + height: 20px; + margin-right: -10px; + } + } +} + .column-settings__outer { background: var(--brand-color--med); padding: 15px; diff --git a/app/styles/navigation.scss b/app/styles/navigation.scss index 158a231bf..9a8a48a44 100644 --- a/app/styles/navigation.scss +++ b/app/styles/navigation.scss @@ -166,6 +166,17 @@ font-weight: bold; } + &__cog { + display: flex; + align-items: center; + justify-content: center; + + .svg-icon { + width: 20px; + height: 20px; + } + } + @media (min-width: 580px) { border-top-left-radius: 10px; border-top-right-radius: 10px;