diff --git a/app/javascript/mastodon/actions/search.js b/app/javascript/mastodon/actions/search.js
index 38a089b486..a34a490e76 100644
--- a/app/javascript/mastodon/actions/search.js
+++ b/app/javascript/mastodon/actions/search.js
@@ -179,6 +179,11 @@ export const openURL = (value, history, onFailure) => (dispatch, getState) => {
export const clickSearchResult = (q, type) => (dispatch, getState) => {
const previous = getState().getIn(['search', 'recent']);
+
+ if (previous.some(x => x.get('q') === q && x.get('type') === type)) {
+ return;
+ }
+
const me = getState().getIn(['meta', 'me']);
const current = previous.add(fromJS({ type, q })).takeLast(4);
@@ -207,4 +212,4 @@ export const hydrateSearch = () => (dispatch, getState) => {
if (history !== null) {
dispatch(updateSearchHistory(history));
}
-};
\ No newline at end of file
+};
diff --git a/app/javascript/mastodon/features/compose/components/search.jsx b/app/javascript/mastodon/features/compose/components/search.jsx
index 0bcc41b929..ca02c23fc4 100644
--- a/app/javascript/mastodon/features/compose/components/search.jsx
+++ b/app/javascript/mastodon/features/compose/components/search.jsx
@@ -62,14 +62,14 @@ class Search extends PureComponent {
};
defaultOptions = [
- { label: <>has: >, action: e => { e.preventDefault(); this._insertText('has:'); } },
- { label: <>is: >, action: e => { e.preventDefault(); this._insertText('is:'); } },
- { label: <>language: >, action: e => { e.preventDefault(); this._insertText('language:'); } },
- { label: <>from: >, action: e => { e.preventDefault(); this._insertText('from:'); } },
- { label: <>before: >, action: e => { e.preventDefault(); this._insertText('before:'); } },
- { label: <>during: >, action: e => { e.preventDefault(); this._insertText('during:'); } },
- { label: <>after: >, action: e => { e.preventDefault(); this._insertText('after:'); } },
- { label: <>in: >, action: e => { e.preventDefault(); this._insertText('in:'); } }
+ { key: 'prompt-has', label: <>has: >, action: e => { e.preventDefault(); this._insertText('has:'); } },
+ { key: 'prompt-is', label: <>is: >, action: e => { e.preventDefault(); this._insertText('is:'); } },
+ { key: 'prompt-language', label: <>language: >, action: e => { e.preventDefault(); this._insertText('language:'); } },
+ { key: 'prompt-from', label: <>from: >, action: e => { e.preventDefault(); this._insertText('from:'); } },
+ { key: 'prompt-before', label: <>before: >, action: e => { e.preventDefault(); this._insertText('before:'); } },
+ { key: 'prompt-during', label: <>during: >, action: e => { e.preventDefault(); this._insertText('during:'); } },
+ { key: 'prompt-after', label: <>after: >, action: e => { e.preventDefault(); this._insertText('after:'); } },
+ { key: 'prompt-in', label: <>in: >, action: e => { e.preventDefault(); this._insertText('in:'); } }
];
setRef = c => {
@@ -262,6 +262,8 @@ class Search extends PureComponent {
const { recent } = this.props;
return recent.toArray().map(search => ({
+ key: `${search.get('type')}/${search.get('q')}`,
+
label: labelForRecentSearch(search),
action: () => this.handleRecentSearchClick(search),
@@ -346,8 +348,8 @@ class Search extends PureComponent {
- {recent.size > 0 ? this._getOptions().map(({ label, action, forget }, i) => (
-