diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index 194823a79..d44fc4503 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -1,7 +1,7 @@ import { omit, reject } from 'lodash'; import { normalize } from '../../types/PhoneNumber'; -import { SearchOptions } from '../../types/Search'; +import { SearchOptions, AdvancedSearchOptions } from '../../types/Search'; import { trigger } from '../../shims/events'; import { getMessageModel } from '../../shims/Whisper'; import { cleanSearchTerm } from '../../util/cleanSearchTerm'; @@ -98,12 +98,28 @@ async function doSearch( ): Promise { const { regionCode } = options; + const advancedSearchOptions = getAdvancedSearchOptionsFromQuery(query); + const processedQuery = advancedSearchOptions['query']; + const isAdvancedQuery = query !== processedQuery; + const [discussions, messages] = await Promise.all([ - queryConversationsAndContacts(query, options), - queryMessages(query), + queryConversationsAndContacts(processedQuery, options), + queryMessages(processedQuery) ]); const { conversations, contacts } = discussions; - const filteredMessages = messages.filter(message => message !== undefined); + let filteredMessages = messages.filter(message => message !== undefined); + + if (isAdvancedQuery) { + let senderFilter: string[] = []; + if (advancedSearchOptions['from'] !== null && advancedSearchOptions['from'].length > 0) { + const senderFilterQuery = await queryConversationsAndContacts(advancedSearchOptions['from'], options); + senderFilter = senderFilterQuery.contacts; + console.log(senderFilter); + } + filteredMessages = filterMessages(filteredMessages, advancedSearchOptions, senderFilter); + console.log(filteredMessages); + console.log(advancedSearchOptions); + } return { query, @@ -146,6 +162,69 @@ function startNewConversation( // Helper functions for search +function filterMessages(messages: any[], filters: AdvancedSearchOptions, contacts: string[]) { + let filteredMessages = messages; + if (filters['from'] !== null && filters['from'].length > 0) { + if (filters['from'] === '@me') { + filteredMessages = filteredMessages.filter(message => message.sent); + } else { + filteredMessages = []; + for(let contact of contacts) { + for (const message of messages) { + if (message.source === contact) { + filteredMessages.push(message); + } + } + } + } + } + if (filters['before'] > 0) { + filteredMessages = filteredMessages.filter(message => message.received_at < filters['before']); + } + if (filters['after'] > 0) { + filteredMessages = filteredMessages.filter(message => message.received_at > filters['after']); + } + + return filteredMessages; +}; + +function getUnixTimestampParameter(timestamp: string): number { + if (!isNaN(parseInt(timestamp))) { + return parseInt(timestamp); + } else { + // ToDo: (konstantinullrich) Add Support for dateformats + return 0; + } +} + +function getAdvancedSearchOptionsFromQuery(query: string): AdvancedSearchOptions { + const filterSeperator = ':'; + const filters: any = { + query: null, + from: null, + before: null, + after: null + }; + + let newQuery = query; + const splitQuery = query.toLowerCase().split(' '); + const filtersList = Object.keys(filters); + for(let queryPart of splitQuery) { + for(let filter of filtersList) { + const filterMatcher = filter + filterSeperator; + if(queryPart.startsWith(filterMatcher)) { + filters[filter] = queryPart.replace(filterMatcher, ''); + newQuery = newQuery.replace(queryPart, '').trim(); + } + } + } + + filters['before'] = getUnixTimestampParameter(filters['before']); + filters['after'] = getUnixTimestampParameter(filters['after']); + filters['query'] = newQuery; + return filters; +}; + const getMessageProps = (messages: Array) => { if (!messages || !messages.length) { return []; diff --git a/ts/types/Search.ts b/ts/types/Search.ts index debd559a0..22cd091cb 100644 --- a/ts/types/Search.ts +++ b/ts/types/Search.ts @@ -4,3 +4,10 @@ export type SearchOptions = { noteToSelf: string; isSecondaryDevice: boolean; }; + +export type AdvancedSearchOptions = { + query: string; + from: string; + before: number; + after: number; +}; \ No newline at end of file