~cytrogen/masto-fe

bceb8931591b4b9df6e8dcfb47864c230884262c — Eugen Rochko 2 years ago 67166de
Add search options to search popout in web UI (#26662)

M app/javascript/mastodon/features/compose/components/search.jsx => app/javascript/mastodon/features/compose/components/search.jsx +42 -5
@@ 1,7 1,7 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';

import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { defineMessages, injectIntl, FormattedMessage, FormattedList } from 'react-intl';

import classNames from 'classnames';



@@ 45,6 45,16 @@ class Search extends PureComponent {
    options: [],
  };

  defaultOptions = [
    { label: <><mark>has:</mark> <FormattedList type='disjunction' value={['media', 'poll', 'embed']} /></>, action: e => { e.preventDefault(); this._insertText('has:') } },
    { label: <><mark>is:</mark> <FormattedList type='disjunction' value={['reply', 'sensitive']} /></>, action: e => { e.preventDefault(); this._insertText('is:') } },
    { label: <><mark>language:</mark> <FormattedMessage id='search_popout.language_code' defaultMessage='ISO language code' /></>, action: e => { e.preventDefault(); this._insertText('language:') } },
    { label: <><mark>from:</mark> <FormattedMessage id='search_popout.user' defaultMessage='user' /></>, action: e => { e.preventDefault(); this._insertText('from:') } },
    { label: <><mark>before:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => { e.preventDefault(); this._insertText('before:') } },
    { label: <><mark>during:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => { e.preventDefault(); this._insertText('during:') } },
    { label: <><mark>after:</mark> <FormattedMessage id='search_popout.specific_date' defaultMessage='specific date' /></>, action: e => { e.preventDefault(); this._insertText('after:') } },
  ];

  setRef = c => {
    this.searchForm = c;
  };


@@ 70,7 80,7 @@ class Search extends PureComponent {

  handleKeyDown = (e) => {
    const { selectedOption } = this.state;
    const options = this._getOptions();
    const options = this._getOptions().concat(this.defaultOptions);

    switch(e.key) {
    case 'Escape':


@@ 100,11 110,9 @@ class Search extends PureComponent {
      if (selectedOption === -1) {
        this._submit();
      } else if (options.length > 0) {
        options[selectedOption].action();
        options[selectedOption].action(e);
      }

      this._unfocus();

      break;
    case 'Delete':
      if (selectedOption > -1 && options.length > 0) {


@@ 147,6 155,7 @@ class Search extends PureComponent {

    router.history.push(`/tags/${query}`);
    onClickSearchResult(query, 'hashtag');
    this._unfocus();
  };

  handleAccountClick = () => {


@@ 157,6 166,7 @@ class Search extends PureComponent {

    router.history.push(`/@${query}`);
    onClickSearchResult(query, 'account');
    this._unfocus();
  };

  handleURLClick = () => {


@@ 164,6 174,7 @@ class Search extends PureComponent {
    const { value, onOpenURL } = this.props;

    onOpenURL(value, router.history);
    this._unfocus();
  };

  handleStatusSearch = () => {


@@ 182,6 193,8 @@ class Search extends PureComponent {
    } else if (search.get('type') === 'hashtag') {
      router.history.push(`/tags/${search.get('q')}`);
    }

    this._unfocus();
  };

  handleForgetRecentSearchClick = search => {


@@ 194,6 207,18 @@ class Search extends PureComponent {
    document.querySelector('.ui').parentElement.focus();
  }

  _insertText (text) {
    const { value, onChange } = this.props;

    if (value === '') {
      onChange(text);
    } else if (value[value.length - 1] === ' ') {
      onChange(`${value}${text}`);
    } else {
      onChange(`${value} ${text}`);
    }
  }

  _submit (type) {
    const { onSubmit, openInRoute } = this.props;
    const { router } = this.context;


@@ 203,6 228,8 @@ class Search extends PureComponent {
    if (openInRoute) {
      router.history.push('/search');
    }

    this._unfocus();
  }

  _getOptions () {


@@ 325,6 352,16 @@ class Search extends PureComponent {
              </div>
            </>
          )}

          <h4><FormattedMessage id='search_popout.options' defaultMessage='Search options' /></h4>

          <div className='search__popout__menu'>
            {this.defaultOptions.map(({ key, label, action }, i) => (
              <button key={key} onMouseDown={action} className={classNames('search__popout__menu__item', { selected: selectedOption === (options.length + i) })}>
                {label}
              </button>
            ))}
          </div>
        </div>
      </div>
    );

M app/javascript/mastodon/locales/en.json => app/javascript/mastodon/locales/en.json +4 -0
@@ 586,8 586,12 @@
  "search.quick_action.open_url": "Open URL in Mastodon",
  "search.quick_action.status_search": "Posts matching {x}",
  "search.search_or_paste": "Search or paste URL",
  "search_popout.language_code": "ISO language code",
  "search_popout.options": "Search options",
  "search_popout.quick_actions": "Quick actions",
  "search_popout.recent": "Recent searches",
  "search_popout.specific_date": "specific date",
  "search_popout.user": "user",
  "search_results.accounts": "Profiles",
  "search_results.all": "All",
  "search_results.hashtags": "Hashtags",

M app/javascript/styles/mastodon/components.scss => app/javascript/styles/mastodon/components.scss +6 -0
@@ 4991,6 4991,12 @@ a.status-card {
    }

    &__menu {
      margin-bottom: 20px;

      &:last-child {
        margin-bottom: 0;
      }

      &__message {
        color: $dark-text-color;
        padding: 0 10px;