@@ 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>
);
@@ 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",