Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions app/internal_packages/thread-list/lib/thread-list-store.es6
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
Rx,
Actions,
WorkspaceStore,
FocusedContentStore,
FocusedPerspectiveStore,
} from 'mailspring-exports';
import { Rx, Actions, FocusedContentStore, FocusedPerspectiveStore } from 'mailspring-exports';
import { ListTabular } from 'mailspring-component-kit';
import ThreadListDataSource from './thread-list-data-source';
import { ipcRenderer } from 'electron';
Expand All @@ -13,8 +7,10 @@ import MailspringStore from 'mailspring-store';
class ThreadListStore extends MailspringStore {
constructor() {
super();
this._limitSearchDate = true;
this.listenTo(FocusedPerspectiveStore, this._onPerspectiveChanged);
ipcRenderer.on('refresh-start-of-day', this._onRefreshStartOfDay);
Actions.expandSearchDate.listen(this._onExpandSearchDate);
this.createListDataSource();
}
_onRefreshStartOfDay = () => {
Expand All @@ -25,6 +21,33 @@ class ThreadListStore extends MailspringStore {
setTimeout(this.createListDataSource, 100);
}
};
limitSearchDate = () => {
return this._limitSearchDate;
};
_onExpandSearchDate = () => {
const currentPerspective = FocusedPerspectiveStore.current();
if (currentPerspective && currentPerspective.isSearchMailbox && this._limitSearchDate) {
this._limitSearchDate = false;
if (typeof this._dataSourceUnlisten === 'function') {
this._dataSourceUnlisten();
}

if (this._dataSource) {
this._dataSource.cleanup();
this._dataSource = null;
}

const threadsSubscription = FocusedPerspectiveStore.current().threads(false);
console.warn('subscription changed');
if (threadsSubscription) {
this._dataSource = new ThreadListDataSource(threadsSubscription);
this._dataSourceUnlisten = this._dataSource.listen(this._onDataChanged);
} else {
this._dataSource = new ListTabular.DataSource.Empty();
}
this.trigger(this);
}
};

dataSource = () => {
return this._dataSource;
Expand Down Expand Up @@ -63,6 +86,7 @@ class ThreadListStore extends MailspringStore {
// Inbound Events

_onPerspectiveChanged = () => {
this._limitSearchDate = true;
if (AppEnv.isMainWindow()) {
this.createListDataSource();
} else {
Expand All @@ -71,6 +95,15 @@ class ThreadListStore extends MailspringStore {
};

_onDataChanged = ({ previous, next } = {}) => {
// If in SearchMailBox, and we returned less than 100 results,
// we want to expand our search scope
const currentPerspective = FocusedPerspectiveStore.current();
if (next && currentPerspective && currentPerspective.isSearchMailbox) {
if (next.empty() || next._ids.length < 100) {
//defer until next cycle, give UI time to display no results page if no results are found
setTimeout(() => Actions.expandSearchDate());
}
}
// This code keeps the focus and keyboard cursor in sync with the thread list.
// When the thread list changes, it looks to see if the focused thread is gone,
// or no longer matches the query criteria and advances the focus to the next
Expand Down
5 changes: 4 additions & 1 deletion app/internal_packages/thread-list/lib/thread-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ class ThreadList extends React.Component {
footer={this._getFooter()}
stores={[ThreadListStore]}
getStateFromStores={() => {
return { dataSource: ThreadListStore.dataSource() };
return {
dataSource: ThreadListStore.dataSource(),
limitSearchDate: ThreadListStore.limitSearchDate(),
};
}}
>
<FocusContainer collection="thread">
Expand Down
2 changes: 2 additions & 0 deletions app/internal_packages/thread-search/lib/search-bar-util.es6
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const wrapInQuotes = s => `"${s.replace(/"/g, '')}"`;
export const getThreadSuggestions = async (term, accountIds) => {
let dbQuery = DatabaseStore.findAll(Thread)
.where({ state: 0 })
.background()
.setQueryType(Constant.QUERY_TYPE.SEARCH_SUBJECT)
.where([Thread.attributes.subject.like(term)])
.order(Thread.attributes.lastMessageTimestamp.descending())
.limit(10);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import SearchQuerySubscription from './search-query-subscription';

class SearchMailboxPerspective extends MailboxPerspective {
constructor(sourcePerspective, searchQuery) {
constructor(sourcePerspective, searchQuery, limitSearchDate) {
super(sourcePerspective.accountIds);
if (typeof searchQuery !== 'string') {
throw new Error('SearchMailboxPerspective: Expected a `string` search query');
Expand Down Expand Up @@ -43,8 +43,8 @@ class SearchMailboxPerspective extends MailboxPerspective {
return super.isEqual(other) && other.searchQuery === this.searchQuery;
}

threads() {
return new SearchQuerySubscription(this.searchQuery, this.accountIds);
threads(limitSearchDate = true) {
return new SearchQuerySubscription(this.searchQuery, this.accountIds, limitSearchDate);
}

canReceiveThreadsFromAccountIds() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import {
const utf7 = require('utf7').imap;

class SearchQuerySubscription extends MutableQuerySubscription {
constructor(searchQuery, accountIds) {
constructor(searchQuery, accountIds, limitSearchDate = true) {
super(null, { emitResultSet: true });
this._searchQuery = searchQuery;
this._accountIds = accountIds;
this._limitSearchDate = limitSearchDate;

this._connections = [];
this._extDisposables = [];
Expand All @@ -42,7 +43,16 @@ class SearchQuerySubscription extends MutableQuerySubscription {
}
let parsedQuery = null;
try {
parsedQuery = SearchQueryParser.parse(this._searchQuery);
let tmpSearchQuery = this._searchQuery;
if (
this._limitSearchDate &&
!tmpSearchQuery.toLocaleUpperCase().includes('BEFORE:') &&
!tmpSearchQuery.toLocaleUpperCase().includes('AFTER:') &&
!tmpSearchQuery.toLocaleUpperCase().includes('SINCE:')
) {
tmpSearchQuery = `( ${tmpSearchQuery} ) AND SINCE: "a month ago"`;
}
parsedQuery = SearchQueryParser.parse(tmpSearchQuery);
// const firstInQueryExpression = parsedQuery.getFirstInQueryExpression();
// if (!firstInQueryExpression) {
// const defaultFolder = new Set();
Expand Down
15 changes: 14 additions & 1 deletion app/internal_packages/thread-search/lib/search-store.es6
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ class SearchStore extends MailspringStore {

this._searchQuery = FocusedPerspectiveStore.current().searchQuery || '';
this._isSearching = false;
this._limitSearchDate = true;

this.listenTo(WorkspaceStore, this._onWorkspaceChange);
this.listenTo(FocusedPerspectiveStore, this._onPerspectiveChanged);
this.listenTo(Actions.searchQuerySubmitted, this._onQuerySubmitted);
this.listenTo(Actions.searchQueryChanged, this._onQueryChanged);
this.listenTo(Actions.searchCompleted, this._onSearchCompleted);
// this.listenTo(Actions.expandSearchDate, this._onExpandSearchDate);
}

query() {
Expand Down Expand Up @@ -108,12 +110,20 @@ class SearchStore extends MailspringStore {
this._searchQuery = FocusedPerspectiveStore.current().searchQuery || '';
this.trigger();
};
_onExpandSearchDate = () => {
if (this._limitSearchDate) {
this._limitSearchDate = false;
this._processAndSubmitQuery();
this._throttleOnQuerySubmitted(this._searchQuery, true);
}
};

_onQueryChanged = query => {
if (query !== this._searchQuery) {
this._searchQuery = query;
this._limitSearchDate = true;
this.trigger();
this._processAndSubmitQuery();
// this._processAndSubmitQuery();
this._throttleOnQuerySubmitted(query, true);
}
};
Expand Down Expand Up @@ -151,6 +161,9 @@ class SearchStore extends MailspringStore {
_onQuerySubmitted = (query, forceQuery) => {
if (query !== this._searchQuery || forceQuery) {
this._searchQuery = query;
if (query !== this._searchQuery) {
this._limitSearchDate = true;
}
this._preSearchQuery = query;
this.trigger();
this._processAndSubmitQuery(forceQuery);
Expand Down
50 changes: 40 additions & 10 deletions app/src/components/list-tabular.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@ import ListDataSource from './list-data-source';
import ListSelection from './list-selection';
import ListTabularItem from './list-tabular-item';
import IFrameSearcher from '../searchable-components/iframe-searcher';
// const {
// GenericQueryExpression,
// AndQueryExpression,
// SubjectQueryExpression,
// FromQueryExpression,
// } = SearchQueryAST;

const ConfigProfileKey = 'core.appearance.profile';

class ListColumn {
Expand Down Expand Up @@ -165,7 +160,17 @@ class ListTabular extends Component {

UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.dataSource !== this.props.dataSource) {
this.setupDataSource(nextProps.dataSource);
const currentPerspective = FocusedPerspectiveStore.current();
if (
currentPerspective &&
currentPerspective.isSearchMailbox &&
!nextProps.limitSearchDate &&
this.props.limitSearchDate
) {
this.setupDataSource(nextProps.dataSource, true);
} else {
this.setupDataSource(nextProps.dataSource);
}
}
if (nextProps.itemHeight !== this.props.itemHeight) {
this.updateRangeState(nextProps);
Expand All @@ -179,7 +184,19 @@ class ListTabular extends Component {
// If our view has been swapped out for an entirely different one,
// reset our scroll position to the top.
if (prevProps.dataSource !== this.props.dataSource) {
this._scrollRegion.scrollTop = 0;
const currentPerspective = FocusedPerspectiveStore.current();
if (
!(
currentPerspective &&
currentPerspective.isSearchMailbox &&
prevProps.limitSearchDate &&
!this.props.limitSearchDate
)
) {
this._scrollRegion.scrollTop = 0;
} else {
console.log('limit search date changed, ignoring retaining scroll');
}
}

if (!this.updateRangeStateFiring) {
Expand Down Expand Up @@ -288,14 +305,19 @@ class ListTabular extends Component {
}
};

setupDataSource(dataSource) {
setupDataSource(dataSource, retainRange = false) {
this._unlisten();
this._unlisten = dataSource.listen(() => {
if (this.mounted) {
this._safeSetState(this.buildStateForRange());
}
});
this._safeSetState(this.buildStateForRange({ start: -1, end: -1, dataSource }));
if (retainRange) {
console.log('retained range');
this._safeSetState(this.buildStateForRange({ dataSource, retainRange }));
} else {
this._safeSetState(this.buildStateForRange({ start: -1, end: -1, dataSource }));
}
}

getRowsToRender() {
Expand Down Expand Up @@ -374,7 +396,15 @@ class ListTabular extends Component {
start = this.state.renderedRangeStart,
end = this.state.renderedRangeEnd,
dataSource = this.props.dataSource,
retainRange,
} = args;
if (retainRange) {
dataSource.setRetainedRange({
start,
end,
});
return;
}

const items = {};
let animatingOut = {};
Expand Down
2 changes: 2 additions & 0 deletions app/src/components/multiselect-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MultiselectList extends React.Component {

static propTypes = {
dataSource: PropTypes.object,
limitSearchDate: PropTypes.bool,
className: PropTypes.string.isRequired,
columns: PropTypes.array.isRequired,
columnCheckProvider: PropTypes.func,
Expand Down Expand Up @@ -180,6 +181,7 @@ class MultiselectList extends React.Component {
ref="list"
columns={this.state.computedColumns}
dataSource={this.props.dataSource}
limitSearchDate={this.props.limitSearchDate}
itemPropsProvider={this.itemPropsProvider}
onSelect={this._onClickItem}
onComponentDidUpdate={this.props.onComponentDidUpdate}
Expand Down
1 change: 1 addition & 0 deletions app/src/constant.es6
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const QUERY_TYPE = {
BACKGROUND: 'BACKGROUND',
SEARCH_PERSPECTIVE: 'SEARCH_PERSPECTIVE',
SEARCH_SUBJECT: 'SEARCH_SUBJECT',
};
Expand Down
1 change: 1 addition & 0 deletions app/src/flux/actions.es6
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ class Actions {
static searchQuerySubmitted = ActionScopeWindow;
static searchQueryChanged = ActionScopeWindow;
static searchCompleted = ActionScopeWindow;
static expandSearchDate = ActionScopeWindow;

static updateChatPanelHeight = ActionScopeMainWindow;
static expandChatPanelFiller = ActionScopeMainWindow;
Expand Down
6 changes: 5 additions & 1 deletion app/src/flux/models/query-subscription.es6
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import DatabaseStore from '../stores/database-store';
import QueryRange from './query-range';
import MutableQueryResultSet from './mutable-query-result-set';
import Thread from './thread';
import { QUERY_TYPE } from '../../constant';

const isMessageView = AppEnv.isDisableThreading();

Expand Down Expand Up @@ -242,11 +243,14 @@ export default class QuerySubscription {
_getQueryForRange = (range, fetchEntireModels) => {
let rangeQuery = null;
if (!range.isInfinite()) {
rangeQuery = rangeQuery || this._query.clone();
rangeQuery = this._query.clone();
rangeQuery.offset(range.offset).limit(range.limit);
}
if (!fetchEntireModels) {
rangeQuery = rangeQuery || this._query.clone();
if (rangeQuery.queryType() && rangeQuery.isBackground()) {
rangeQuery.setQueryType(QUERY_TYPE.BACKGROUND);
}
rangeQuery.idsOnly();
}
rangeQuery = rangeQuery || this._query;
Expand Down
3 changes: 3 additions & 0 deletions app/src/flux/models/query.es6
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ export default class ModelQuery {
this._background = true;
return this;
}
isBackground() {
return this._background;
}
setQueryType(queryType) {
this._queryType = queryType;
return this;
Expand Down
4 changes: 2 additions & 2 deletions app/src/flux/stores/database-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ const dbs = {};

const deathDelay = 50000;
const args = process.argv.slice(2);
if (args.length > 0) {
if (args.length > 1) {
LOG.transports.file.file = path.join(
args[0],
'ui-log',
`ui-log-database-agent-${Date.now()}.log`
`ui-log-database-agent-${args[1]}-${Date.now()}.log`
);
LOG.transports.console.level = false;
LOG.transports.file.maxSize = 20485760;
Expand Down
Loading