mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-14 13:44:41 +08:00
d3dcf89e9f
Summary: This commit adds the ability to perform event search in the calendar window. To achieve this, SearchBar has been moved from the thread-search package to be a part of the nylas-component-kit, and reused by both thread-search and nylas-calendar When an event is selected from search results, the calendar view is moved to the selected event. Depends on D3396 to open the event popover. Test Plan: Manual Reviewers: halla, bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D3424
210 lines
5.9 KiB
JavaScript
210 lines
5.9 KiB
JavaScript
import NylasStore from 'nylas-store';
|
|
import {
|
|
Thread,
|
|
Actions,
|
|
ContactStore,
|
|
AccountStore,
|
|
DatabaseStore,
|
|
ComponentRegistry,
|
|
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._extensionData = []
|
|
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;
|
|
const searchExtensions = ComponentRegistry.findComponentsMatching({
|
|
role: "SearchBarResults",
|
|
})
|
|
|
|
Promise.map(searchExtensions, (ext) => {
|
|
return Promise.props({
|
|
label: ext.searchLabel(),
|
|
suggestions: ext.fetchSearchSuggestions(this._searchQuery),
|
|
})
|
|
}).then((extensionData = []) => {
|
|
this._extensionData = extensionData;
|
|
this._compileResults();
|
|
})
|
|
|
|
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).distinct()
|
|
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,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (this._extensionData.length) {
|
|
for (const {label, suggestions} of this._extensionData) {
|
|
this._suggestions.push({divider: label});
|
|
this._suggestions = this._suggestions.concat(suggestions)
|
|
}
|
|
}
|
|
|
|
this.trigger();
|
|
}
|
|
}
|
|
|
|
export default new SearchStore();
|