mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-24 01:06:07 +08:00
ff61527d75
This is a temporary fix which adds defensive code to prevent duplicate results from being returned from the thread search query which causes N1 to enter a loop and freeze (#3001). Duplicate results from the search query likely indicate that a thread was indexed twice, which was not the case before. The cause for this is still at large.
181 lines
5.2 KiB
JavaScript
181 lines
5.2 KiB
JavaScript
import NylasStore from 'nylas-store';
|
|
import { Thread, Actions, ContactStore, AccountStore, DatabaseStore, FocusedPerspectiveStore } from 'nylas-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.
|
|
// For example, we might create a "MessageStore" that observes this store
|
|
// for changes in selectedThread, "DatabaseStore" for changes to the underlying database,
|
|
// and vends up the array used for that view.
|
|
|
|
class SearchStore extends NylasStore {
|
|
constructor() {
|
|
super();
|
|
|
|
this._searchQuery = FocusedPerspectiveStore.current().searchQuery || "";
|
|
this._searchSuggestionsVersion = 1;
|
|
this._isSearching = false;
|
|
this._clearResults();
|
|
|
|
this.listenTo(FocusedPerspectiveStore, this._onPerspectiveChanged);
|
|
this.listenTo(SearchActions.querySubmitted, this._onQuerySubmitted);
|
|
this.listenTo(SearchActions.queryChanged, this._onQueryChanged);
|
|
this.listenTo(SearchActions.searchBlurred, this._onSearchBlurred);
|
|
this.listenTo(SearchActions.searchCompleted, this._onSearchCompleted);
|
|
}
|
|
|
|
query() {
|
|
return this._searchQuery;
|
|
}
|
|
|
|
queryPopulated() {
|
|
return this._searchQuery && this._searchQuery.trim().length > 0;
|
|
}
|
|
|
|
suggestions() {
|
|
return this._suggestions;
|
|
}
|
|
|
|
isSearching() {
|
|
return this._isSearching;
|
|
}
|
|
|
|
_onSearchCompleted = () => {
|
|
this._isSearching = false;
|
|
this.trigger();
|
|
}
|
|
|
|
_onPerspectiveChanged = () => {
|
|
this._searchQuery = FocusedPerspectiveStore.current().searchQuery || "";
|
|
this.trigger();
|
|
}
|
|
|
|
_onQueryChanged = (query) => {
|
|
this._searchQuery = query;
|
|
if (this._searchQuery.length <= 1) {
|
|
this.trigger()
|
|
return
|
|
}
|
|
this._compileResults();
|
|
setTimeout(() => this._rebuildResults(), 0);
|
|
}
|
|
|
|
_onQuerySubmitted = (query) => {
|
|
this._searchQuery = query;
|
|
const current = FocusedPerspectiveStore.current();
|
|
|
|
if (this.queryPopulated()) {
|
|
this._isSearching = true;
|
|
if (this._perspectiveBeforeSearch == null) {
|
|
this._perspectiveBeforeSearch = current;
|
|
}
|
|
const next = new SearchMailboxPerspective(current.accountIds, this._searchQuery.trim());
|
|
Actions.focusMailboxPerspective(next);
|
|
} else if (current instanceof SearchMailboxPerspective) {
|
|
if (this._perspectiveBeforeSearch) {
|
|
Actions.focusMailboxPerspective(this._perspectiveBeforeSearch);
|
|
this._perspectiveBeforeSearch = null;
|
|
} else {
|
|
Actions.focusDefaultMailboxPerspectiveForAccounts(AccountStore.accounts());
|
|
}
|
|
}
|
|
|
|
this._clearResults();
|
|
}
|
|
|
|
_onSearchBlurred = () => {
|
|
this._clearResults();
|
|
}
|
|
|
|
_clearResults() {
|
|
this._searchSuggestionsVersion = 1;
|
|
this._threadResults = [];
|
|
this._contactResults = [];
|
|
this._suggestions = [];
|
|
this.trigger();
|
|
}
|
|
|
|
_rebuildResults() {
|
|
if (!this.queryPopulated()) {
|
|
this._clearResults();
|
|
return;
|
|
}
|
|
this._searchSuggestionsVersion += 1;
|
|
this._fetchThreadResults();
|
|
this._fetchContactResults();
|
|
}
|
|
|
|
_fetchContactResults() {
|
|
const version = this._searchSuggestionsVersion;
|
|
ContactStore.searchContacts(this._searchQuery, {limit: 10}).then(contacts => {
|
|
if (version !== this._searchSuggestionsVersion) {
|
|
return;
|
|
}
|
|
this._contactResults = contacts;
|
|
this._compileResults();
|
|
});
|
|
}
|
|
|
|
_fetchThreadResults() {
|
|
if (this._fetchingThreadResultsVersion) { return; }
|
|
this._fetchingThreadResultsVersion = this._searchSuggestionsVersion;
|
|
|
|
const {accountIds} = FocusedPerspectiveStore.current();
|
|
let dbQuery = DatabaseStore.findAll(Thread)
|
|
if (Array.isArray(accountIds) && accountIds.length === 1) {
|
|
dbQuery = dbQuery.where({accountId: accountIds[0]})
|
|
}
|
|
dbQuery = dbQuery
|
|
.search(this._searchQuery)
|
|
.order(Thread.attributes.lastMessageReceivedTimestamp.descending())
|
|
.limit(4);
|
|
|
|
dbQuery.then(results => {
|
|
// We've fetched the latest thread results - display them!
|
|
if (this._searchSuggestionsVersion === this._fetchingThreadResultsVersion) {
|
|
this._fetchingThreadResultsVersion = null;
|
|
this._threadResults = results;
|
|
this._compileResults();
|
|
// We're behind and need to re-run the search for the latest results
|
|
} else if (this._searchSuggestionsVersion > this._fetchingThreadResultsVersion) {
|
|
this._fetchingThreadResultsVersion = null;
|
|
this._fetchThreadResults();
|
|
} else {
|
|
this._fetchingThreadResultsVersion = null;
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
_compileResults() {
|
|
this._suggestions = [];
|
|
|
|
this._suggestions.push({
|
|
label: `Message Contains: ${this._searchQuery}`,
|
|
value: this._searchQuery,
|
|
});
|
|
|
|
if (this._threadResults.length) {
|
|
this._suggestions.push({divider: 'Threads'});
|
|
for (const thread of this._threadResults) {
|
|
this._suggestions.push({thread});
|
|
}
|
|
}
|
|
|
|
if (this._contactResults.length) {
|
|
this._suggestions.push({divider: 'People'});
|
|
for (const contact of this._contactResults) {
|
|
this._suggestions.push({
|
|
contact: contact,
|
|
value: contact.email,
|
|
});
|
|
}
|
|
}
|
|
|
|
this.trigger();
|
|
}
|
|
}
|
|
|
|
export default new SearchStore();
|