Add right-click search options to threads

This commit is contained in:
Ben Gotow 2018-06-25 00:14:25 -05:00
parent 1977074f55
commit 9376ca0471
7 changed files with 44 additions and 21 deletions

View file

@ -21,6 +21,9 @@ export default class ThreadListContextMenu {
this.threads = threads;
return Promise.all([
this.findWithFrom(),
this.findWithSubject(),
{ type: 'separator' },
this.replyItem(),
this.replyAllItem(),
this.forwardItem(),
@ -41,6 +44,33 @@ export default class ThreadListContextMenu {
});
}
findWithFrom() {
if (this.threadIds.length !== 1) {
return null;
}
const from = this.threads[0].participants.find(p => !p.isMe());
return {
label: `Search for ${from.email}`,
click: () => {
Actions.searchQuerySubmitted(`from:"${from.email.replace('"', '""')}"`);
},
};
}
findWithSubject() {
if (this.threadIds.length !== 1) {
return null;
}
const subject = this.threads[0].subject;
return {
label: `Search for ${subject.length > 35 ? `${subject.substr(0, 35)}...` : subject}`,
click: () => {
Actions.searchQuerySubmitted(`subject:"${subject}"`);
},
};
}
replyItem() {
if (this.threadIds.length !== 1) {
return null;

View file

@ -1,9 +0,0 @@
import Reflux from 'reflux';
const SearchActions = Reflux.createActions(['querySubmitted', 'queryChanged', 'searchCompleted']);
for (const key of Object.keys(SearchActions)) {
SearchActions[key].sync = true;
}
export default SearchActions;

View file

@ -1,5 +1,6 @@
import _ from 'underscore';
import {
Actions,
Thread,
DatabaseStore,
SearchQueryParser,
@ -7,7 +8,6 @@ import {
FocusedContentStore,
MutableQuerySubscription,
} from 'mailspring-exports';
import SearchActions from './search-actions';
class SearchQuerySubscription extends MutableQuerySubscription {
constructor(searchQuery, accountIds) {
@ -61,7 +61,7 @@ class SearchQuerySubscription extends MutableQuerySubscription {
.limit(1000);
dbQuery.then(results => {
SearchActions.searchCompleted();
Actions.searchCompleted();
this.replaceQuery(dbQuery);
});
}

View file

@ -1,7 +1,6 @@
import MailspringStore from 'mailspring-store';
import { Actions, AccountStore, FocusedPerspectiveStore } from 'mailspring-exports';
import SearchActions from './search-actions';
import SearchMailboxPerspective from './search-mailbox-perspective';
// Stores should closely match the needs of a particular part of the front end.
@ -17,9 +16,9 @@ class SearchStore extends MailspringStore {
this._isSearching = false;
this.listenTo(FocusedPerspectiveStore, this._onPerspectiveChanged);
this.listenTo(SearchActions.querySubmitted, this._onQuerySubmitted);
this.listenTo(SearchActions.queryChanged, this._onQueryChanged);
this.listenTo(SearchActions.searchCompleted, this._onSearchCompleted);
this.listenTo(Actions.searchQuerySubmitted, this._onQuerySubmitted);
this.listenTo(Actions.searchQueryChanged, this._onQueryChanged);
this.listenTo(Actions.searchCompleted, this._onSearchCompleted);
}
query() {

View file

@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { ListensToFluxStore, RetinaImg } from 'mailspring-component-kit';
import { Actions, FocusedPerspectiveStore, WorkspaceStore } from 'mailspring-exports';
import SearchStore from './search-store';
import SearchActions from './search-actions';
import TokenizingContenteditable from './tokenizing-contenteditable';
import {
@ -174,7 +173,7 @@ class ThreadSearchBar extends Component {
};
_onSearchQueryChanged = async query => {
SearchActions.queryChanged(query);
Actions.searchQueryChanged(query);
if (query === '') {
this._onClearSearchQuery();
}
@ -195,12 +194,12 @@ class ThreadSearchBar extends Component {
};
_onSubmitSearchQuery = nextQuery => {
SearchActions.querySubmitted(nextQuery);
Actions.searchQuerySubmitted(nextQuery);
this._fieldEl.blur();
};
_onClearSearchQuery = () => {
SearchActions.querySubmitted('');
Actions.searchQuerySubmitted('');
};
_placeholder = () => {

View file

@ -18,10 +18,10 @@ describe('ThreadSearchBar', function() {
});
it('supports search queries with a colon character', function() {
spyOn(SearchActions, 'queryChanged');
spyOn(SearchActions, 'searchQueryChanged');
const test = '::Hello: World::';
ReactTestUtils.Simulate.change(this.input, { target: { value: test } });
expect(SearchActions.queryChanged).toHaveBeenCalledWith(test);
expect(SearchActions.searchQueryChanged).toHaveBeenCalledWith(test);
});
it('preserves capitalization on searches', function() {

View file

@ -489,6 +489,10 @@ class Actions {
static toggleAccount = ActionScopeWindow;
static expandSyncState = ActionScopeWindow;
static searchQuerySubmitted = ActionScopeWindow;
static searchQueryChanged = ActionScopeWindow;
static searchCompleted = ActionScopeWindow;
}
// Read the actions we declared on the dummy Actions object above