From 924ffe81d477a8cf890c8117efb94b908760bccc Mon Sep 17 00:00:00 2001 From: kibigo! Date: Sat, 23 Dec 2017 22:16:45 -0800 Subject: WIPgit status Refactor; ed. --- .../features/drawer/components/navigation_bar.js | 38 ++++ .../glitch/features/drawer/components/search.js | 129 ++++++++++++++ .../features/drawer/components/search_results.js | 65 +++++++ .../drawer/containers/navigation_container.js | 11 ++ .../features/drawer/containers/search_container.js | 35 ++++ .../drawer/containers/search_results_container.js | 8 + .../flavours/glitch/features/drawer/index.js | 198 +++++++++++++++++++++ 7 files changed, 484 insertions(+) create mode 100644 app/javascript/flavours/glitch/features/drawer/components/navigation_bar.js create mode 100644 app/javascript/flavours/glitch/features/drawer/components/search.js create mode 100644 app/javascript/flavours/glitch/features/drawer/components/search_results.js create mode 100644 app/javascript/flavours/glitch/features/drawer/containers/navigation_container.js create mode 100644 app/javascript/flavours/glitch/features/drawer/containers/search_container.js create mode 100644 app/javascript/flavours/glitch/features/drawer/containers/search_results_container.js create mode 100644 app/javascript/flavours/glitch/features/drawer/index.js (limited to 'app/javascript/flavours/glitch/features/drawer') diff --git a/app/javascript/flavours/glitch/features/drawer/components/navigation_bar.js b/app/javascript/flavours/glitch/features/drawer/components/navigation_bar.js new file mode 100644 index 000000000..1b6d74123 --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/components/navigation_bar.js @@ -0,0 +1,38 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import Avatar from 'flavours/glitch/components/avatar'; +import IconButton from 'flavours/glitch/components/icon_button'; +import Permalink from 'flavours/glitch/components/permalink'; +import { FormattedMessage } from 'react-intl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; + +export default class NavigationBar extends ImmutablePureComponent { + + static propTypes = { + account: ImmutablePropTypes.map.isRequired, + onClose: PropTypes.func.isRequired, + }; + + render () { + return ( +
+ + {this.props.account.get('acct')} + + + +
+ + @{this.props.account.get('acct')} + + + +
+ + +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/features/drawer/components/search.js b/app/javascript/flavours/glitch/features/drawer/components/search.js new file mode 100644 index 000000000..1ce66b19d --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/components/search.js @@ -0,0 +1,129 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import Overlay from 'react-overlays/lib/Overlay'; +import Motion from 'flavours/glitch/util/optional_motion'; +import spring from 'react-motion/lib/spring'; + +const messages = defineMessages({ + placeholder: { id: 'search.placeholder', defaultMessage: 'Search' }, +}); + +class SearchPopout extends React.PureComponent { + + static propTypes = { + style: PropTypes.object, + }; + + render () { + const { style } = this.props; + + return ( +
+ + {({ opacity, scaleX, scaleY }) => ( +
+

+ +
    +
  • #example
  • +
  • @username@domain
  • +
  • URL
  • +
  • URL
  • +
+ + +
+ )} +
+
+ ); + } + +} + +@injectIntl +export default class Search extends React.PureComponent { + + static propTypes = { + value: PropTypes.string.isRequired, + submitted: PropTypes.bool, + onChange: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onClear: PropTypes.func.isRequired, + onShow: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + + state = { + expanded: false, + }; + + handleChange = (e) => { + this.props.onChange(e.target.value); + } + + handleClear = (e) => { + e.preventDefault(); + + if (this.props.value.length > 0 || this.props.submitted) { + this.props.onClear(); + } + } + + handleKeyDown = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + this.props.onSubmit(); + } else if (e.key === 'Escape') { + document.querySelector('.ui').parentElement.focus(); + } + } + + noop () { + + } + + handleFocus = () => { + this.setState({ expanded: true }); + this.props.onShow(); + } + + handleBlur = () => { + this.setState({ expanded: false }); + } + + render () { + const { intl, value, submitted } = this.props; + const { expanded } = this.state; + const hasValue = value.length > 0 || submitted; + + return ( +
+ + +
+ + +
+ + + + +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/features/drawer/components/search_results.js b/app/javascript/flavours/glitch/features/drawer/components/search_results.js new file mode 100644 index 000000000..2a4818d4e --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/components/search_results.js @@ -0,0 +1,65 @@ +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { FormattedMessage } from 'react-intl'; +import AccountContainer from 'flavours/glitch/containers/account_container'; +import StatusContainer from 'flavours/glitch/containers/status_container'; +import { Link } from 'react-router-dom'; +import ImmutablePureComponent from 'react-immutable-pure-component'; + +export default class SearchResults extends ImmutablePureComponent { + + static propTypes = { + results: ImmutablePropTypes.map.isRequired, + }; + + render () { + const { results } = this.props; + + let accounts, statuses, hashtags; + let count = 0; + + if (results.get('accounts') && results.get('accounts').size > 0) { + count += results.get('accounts').size; + accounts = ( +
+ {results.get('accounts').map(accountId => )} +
+ ); + } + + if (results.get('statuses') && results.get('statuses').size > 0) { + count += results.get('statuses').size; + statuses = ( +
+ {results.get('statuses').map(statusId => )} +
+ ); + } + + if (results.get('hashtags') && results.get('hashtags').size > 0) { + count += results.get('hashtags').size; + hashtags = ( +
+ {results.get('hashtags').map(hashtag => + + #{hashtag} + + )} +
+ ); + } + + return ( +
+
+ +
+ + {accounts} + {statuses} + {hashtags} +
+ ); + } + +} diff --git a/app/javascript/flavours/glitch/features/drawer/containers/navigation_container.js b/app/javascript/flavours/glitch/features/drawer/containers/navigation_container.js new file mode 100644 index 000000000..eb630ffbb --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/containers/navigation_container.js @@ -0,0 +1,11 @@ +import { connect } from 'react-redux'; +import NavigationBar from '../components/navigation_bar'; +import { me } from 'flavours/glitch/util/initial_state'; + +const mapStateToProps = state => { + return { + account: state.getIn(['accounts', me]), + }; +}; + +export default connect(mapStateToProps)(NavigationBar); diff --git a/app/javascript/flavours/glitch/features/drawer/containers/search_container.js b/app/javascript/flavours/glitch/features/drawer/containers/search_container.js new file mode 100644 index 000000000..8f4bfcf08 --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/containers/search_container.js @@ -0,0 +1,35 @@ +import { connect } from 'react-redux'; +import { + changeSearch, + clearSearch, + submitSearch, + showSearch, +} from 'flavours/glitch/actions/search'; +import Search from '../components/search'; + +const mapStateToProps = state => ({ + value: state.getIn(['search', 'value']), + submitted: state.getIn(['search', 'submitted']), +}); + +const mapDispatchToProps = dispatch => ({ + + onChange (value) { + dispatch(changeSearch(value)); + }, + + onClear () { + dispatch(clearSearch()); + }, + + onSubmit () { + dispatch(submitSearch()); + }, + + onShow () { + dispatch(showSearch()); + }, + +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Search); diff --git a/app/javascript/flavours/glitch/features/drawer/containers/search_results_container.js b/app/javascript/flavours/glitch/features/drawer/containers/search_results_container.js new file mode 100644 index 000000000..16d95d417 --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/containers/search_results_container.js @@ -0,0 +1,8 @@ +import { connect } from 'react-redux'; +import SearchResults from '../components/search_results'; + +const mapStateToProps = state => ({ + results: state.getIn(['search', 'results']), +}); + +export default connect(mapStateToProps)(SearchResults); diff --git a/app/javascript/flavours/glitch/features/drawer/index.js b/app/javascript/flavours/glitch/features/drawer/index.js new file mode 100644 index 000000000..8386ae47c --- /dev/null +++ b/app/javascript/flavours/glitch/features/drawer/index.js @@ -0,0 +1,198 @@ +// Package imports. +import PropTypes from 'prop-types'; +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { injectIntl, defineMessages } from 'react-intl'; +import spring from 'react-motion/lib/spring'; +import { connect } from 'react-redux'; +import { Link } from 'react-router-dom'; + +// Actions. +import { changeComposing } from 'flavours/glitch/actions/compose'; +import { changeLocalSetting } from 'flavours/glitch/actions/local_settings'; +import { openModal } from 'flavours/glitch/actions/modal'; + +// Components. +import Icon from 'flavours/glitch/components/icon'; +import Compose from 'flavours/glitch/features/compose'; +import NavigationContainer from './containers/navigation_container'; +import SearchContainer from './containers/search_container'; +import SearchResultsContainer from './containers/search_results_container'; + +// Utils. +import Motion from 'flavours/glitch/util/optional_motion'; +import { + assignHandlers, + conditionalRender, +} from 'flavours/glitch/util/react_helpers'; + +// Messages. +const messages = defineMessages({ + community: { + defaultMessage: 'Local timeline', + id: 'navigation_bar.community_timeline', + }, + home_timeline: { + defaultMessage: 'Home', + id: 'tabs_bar.home', + }, + logout: { + defaultMessage: 'Logout', + id: 'navigation_bar.logout', + }, + notifications: { + defaultMessage: 'Notifications', + id: 'tabs_bar.notifications', + }, + public: { + defaultMessage: 'Federated timeline', + id: 'navigation_bar.public_timeline', + }, + settings: { + defaultMessage: 'App settings', + id: 'navigation_bar.app_settings', + }, + start: { + defaultMessage: 'Getting started', + id: 'getting_started.heading', + }, +}); + +// State mapping. +const mapStateToProps = state => ({ + columns: state.getIn(['settings', 'columns']), + showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), +}); + +// Dispatch mapping. +const mapDispatchToProps = dispatch => ({ + onBlur () { + dispatch(changeComposing(false)); + }, + onFocus () { + dispatch(changeComposing(true)); + }, + onSettingsOpen () { + dispatch(openModal('SETTINGS', {})); + }, +}); + +// The component. +@connect(mapStateToProps, mapDispatchToProps) +@injectIntl +export default function Drawer ({ + columns, + intl, + multiColumn, + onBlur, + onFocus, + onSettingsOpen, + showSearch, +}) { + + // Only renders the component if the column isn't being shown. + const renderForColumn = conditionalRender.bind( + columnId => !columns.some(column => column.get('id') === columnId) + ); + + // The result. + return ( +
+ {multiColumn ? ( + + ) : null} + +
+
+ + +
+ + {({ x }) => ( +
+ )} +
+
+
+ ); +} + +// Props. +Drawer.propTypes = { + dispatch: PropTypes.func.isRequired, + columns: ImmutablePropTypes.list.isRequired, + multiColumn: PropTypes.bool, + showSearch: PropTypes.bool, + intl: PropTypes.object.isRequired, +}; -- cgit