From 8c32bb93f755bf1edf24b025244e1354a5c8f7a5 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Fri, 6 Mar 2020 17:36:55 +0100 Subject: [PATCH 1/9] Implement Advanced Search (from, before and after) --- ts/state/ducks/search.ts | 87 ++++++++++++++++++++++++++++++++++++++-- ts/types/Search.ts | 7 ++++ 2 files changed, 90 insertions(+), 4 deletions(-) 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 From c11a96ad01672f0358733e8d49575662833db6f1 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Fri, 6 Mar 2020 17:43:00 +0100 Subject: [PATCH 2/9] lint --- ts/state/ducks/search.ts | 50 ++++++++++++++++++++++++++++------------ ts/types/Search.ts | 8 +++---- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index d44fc4503..b965c0dc3 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -104,19 +104,29 @@ async function doSearch( const [discussions, messages] = await Promise.all([ queryConversationsAndContacts(processedQuery, options), - queryMessages(processedQuery) + queryMessages(processedQuery), ]); const { conversations, contacts } = discussions; 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); + 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); + filteredMessages = filterMessages( + filteredMessages, + advancedSearchOptions, + senderFilter + ); console.log(filteredMessages); console.log(advancedSearchOptions); } @@ -162,14 +172,18 @@ function startNewConversation( // Helper functions for search -function filterMessages(messages: any[], filters: AdvancedSearchOptions, contacts: string[]) { +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 (let contact of contacts) { for (const message of messages) { if (message.source === contact) { filteredMessages.push(message); @@ -179,14 +193,18 @@ function filterMessages(messages: any[], filters: AdvancedSearchOptions, contact } } if (filters['before'] > 0) { - filteredMessages = filteredMessages.filter(message => message.received_at < filters['before']); + filteredMessages = filteredMessages.filter( + message => message.received_at < filters['before'] + ); } if (filters['after'] > 0) { - filteredMessages = filteredMessages.filter(message => message.received_at > filters['after']); + filteredMessages = filteredMessages.filter( + message => message.received_at > filters['after'] + ); } return filteredMessages; -}; +} function getUnixTimestampParameter(timestamp: string): number { if (!isNaN(parseInt(timestamp))) { @@ -197,22 +215,24 @@ function getUnixTimestampParameter(timestamp: string): number { } } -function getAdvancedSearchOptionsFromQuery(query: string): AdvancedSearchOptions { +function getAdvancedSearchOptionsFromQuery( + query: string +): AdvancedSearchOptions { const filterSeperator = ':'; const filters: any = { query: null, from: null, before: null, - after: 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) { + for (let queryPart of splitQuery) { + for (let filter of filtersList) { const filterMatcher = filter + filterSeperator; - if(queryPart.startsWith(filterMatcher)) { + if (queryPart.startsWith(filterMatcher)) { filters[filter] = queryPart.replace(filterMatcher, ''); newQuery = newQuery.replace(queryPart, '').trim(); } @@ -223,7 +243,7 @@ function getAdvancedSearchOptionsFromQuery(query: string): AdvancedSearchOptions filters['after'] = getUnixTimestampParameter(filters['after']); filters['query'] = newQuery; return filters; -}; +} const getMessageProps = (messages: Array) => { if (!messages || !messages.length) { diff --git a/ts/types/Search.ts b/ts/types/Search.ts index 22cd091cb..990372434 100644 --- a/ts/types/Search.ts +++ b/ts/types/Search.ts @@ -6,8 +6,8 @@ export type SearchOptions = { }; export type AdvancedSearchOptions = { - query: string; - from: string; - before: number; + query: string; + from: string; + before: number; after: number; -}; \ No newline at end of file +}; From 8f7083f5a2fc1003cb6313a553e6ac571910de1b Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Sat, 7 Mar 2020 19:29:46 +0100 Subject: [PATCH 3/9] Update Advanced Search by easier date formats --- ts/state/ducks/search.ts | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index b965c0dc3..0e8449965 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -120,15 +120,12 @@ async function doSearch( options ); senderFilter = senderFilterQuery.contacts; - console.log(senderFilter); } filteredMessages = filterMessages( filteredMessages, advancedSearchOptions, senderFilter ); - console.log(filteredMessages); - console.log(advancedSearchOptions); } return { @@ -206,13 +203,20 @@ function filterMessages( return filteredMessages; } -function getUnixTimestampParameter(timestamp: string): number { - if (!isNaN(parseInt(timestamp))) { - return parseInt(timestamp); - } else { - // ToDo: (konstantinullrich) Add Support for dateformats - return 0; +function getUnixMillisecondsTimestamp(timestamp: string): number { + if(!isNaN(parseInt(timestamp))) { + const timestampInt = parseInt(timestamp); + try { + if (timestampInt > 10000) { + return new Date(timestampInt).getTime(); + } + return new Date(timestamp).getTime(); + } catch (error) { + console.warn('Advanced Search: ' + error); + return 0; + } } + return 0; } function getAdvancedSearchOptionsFromQuery( @@ -239,8 +243,8 @@ function getAdvancedSearchOptionsFromQuery( } } - filters['before'] = getUnixTimestampParameter(filters['before']); - filters['after'] = getUnixTimestampParameter(filters['after']); + filters['before'] = getUnixMillisecondsTimestamp(filters['before']); + filters['after'] = getUnixMillisecondsTimestamp(filters['after']); filters['query'] = newQuery; return filters; } From f770d4ed448ddb63ea963d94ee7714793e4f1e36 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Sat, 7 Mar 2020 19:34:05 +0100 Subject: [PATCH 4/9] lint --- ts/state/ducks/search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index 0e8449965..a85e2ba04 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -204,7 +204,7 @@ function filterMessages( } function getUnixMillisecondsTimestamp(timestamp: string): number { - if(!isNaN(parseInt(timestamp))) { + if (!isNaN(parseInt(timestamp))) { const timestampInt = parseInt(timestamp); try { if (timestampInt > 10000) { From 3eca4025e7edccabbcfd84e1047c323a438e1699 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Sat, 7 Mar 2020 20:30:43 +0100 Subject: [PATCH 5/9] Fix lint in search.ts --- ts/state/ducks/search.ts | 50 ++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index a85e2ba04..37a7b00ea 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, AdvancedSearchOptions } from '../../types/Search'; +import { AdvancedSearchOptions, SearchOptions } from '../../types/Search'; import { trigger } from '../../shims/events'; import { getMessageModel } from '../../shims/Whisper'; import { cleanSearchTerm } from '../../util/cleanSearchTerm'; @@ -99,7 +99,7 @@ async function doSearch( const { regionCode } = options; const advancedSearchOptions = getAdvancedSearchOptionsFromQuery(query); - const processedQuery = advancedSearchOptions['query']; + const processedQuery = advancedSearchOptions.query; const isAdvancedQuery = query !== processedQuery; const [discussions, messages] = await Promise.all([ @@ -110,13 +110,13 @@ async function doSearch( let filteredMessages = messages.filter(message => message !== undefined); if (isAdvancedQuery) { - let senderFilter: string[] = []; + let senderFilter: Array = []; if ( - advancedSearchOptions['from'] !== null && - advancedSearchOptions['from'].length > 0 + advancedSearchOptions.from !== null && + advancedSearchOptions.from.length > 0 ) { const senderFilterQuery = await queryConversationsAndContacts( - advancedSearchOptions['from'], + advancedSearchOptions.from, options ); senderFilter = senderFilterQuery.contacts; @@ -170,17 +170,17 @@ function startNewConversation( // Helper functions for search function filterMessages( - messages: any[], + messages: Array, filters: AdvancedSearchOptions, - contacts: string[] + contacts: Array ) { let filteredMessages = messages; - if (filters['from'] !== null && filters['from'].length > 0) { - if (filters['from'] === '@me') { + 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 contact of contacts) { for (const message of messages) { if (message.source === contact) { filteredMessages.push(message); @@ -189,14 +189,14 @@ function filterMessages( } } } - if (filters['before'] > 0) { + if (filters.before > 0) { filteredMessages = filteredMessages.filter( - message => message.received_at < filters['before'] + message => message.received_at < filters.before ); } - if (filters['after'] > 0) { + if (filters.after > 0) { filteredMessages = filteredMessages.filter( - message => message.received_at > filters['after'] + message => message.received_at > filters.after ); } @@ -204,18 +204,21 @@ function filterMessages( } function getUnixMillisecondsTimestamp(timestamp: string): number { - if (!isNaN(parseInt(timestamp))) { - const timestampInt = parseInt(timestamp); + const timestampInt = parseInt(timestamp, 10); + if (!isNaN(timestampInt)) { try { if (timestampInt > 10000) { return new Date(timestampInt).getTime(); } + return new Date(timestamp).getTime(); } catch (error) { - console.warn('Advanced Search: ' + error); + console.warn('Advanced Search: ', error); + return 0; } } + return 0; } @@ -233,8 +236,8 @@ function getAdvancedSearchOptionsFromQuery( let newQuery = query; const splitQuery = query.toLowerCase().split(' '); const filtersList = Object.keys(filters); - for (let queryPart of splitQuery) { - for (let filter of filtersList) { + for (const queryPart of splitQuery) { + for (const filter of filtersList) { const filterMatcher = filter + filterSeperator; if (queryPart.startsWith(filterMatcher)) { filters[filter] = queryPart.replace(filterMatcher, ''); @@ -243,9 +246,10 @@ function getAdvancedSearchOptionsFromQuery( } } - filters['before'] = getUnixMillisecondsTimestamp(filters['before']); - filters['after'] = getUnixMillisecondsTimestamp(filters['after']); - filters['query'] = newQuery; + filters.before = getUnixMillisecondsTimestamp(filters.before); + filters.after = getUnixMillisecondsTimestamp(filters.after); + filters.query = newQuery; + return filters; } From 048ca2d405b39d8a789da256feb14dd3886a5d8f Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Sat, 7 Mar 2020 21:02:24 +0100 Subject: [PATCH 6/9] fix lint in search.ts --- ts/state/ducks/search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index 37a7b00ea..6064cb66d 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -176,7 +176,7 @@ function filterMessages( ) { let filteredMessages = messages; if (filters.from !== null && filters.from.length > 0) { - if (filters.from=== '@me') { + if (filters.from === '@me') { filteredMessages = filteredMessages.filter(message => message.sent); } else { filteredMessages = []; From 87aee6286d2a0a51c302e9446713df0b4a941245 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 10 Mar 2020 06:43:34 +0100 Subject: [PATCH 7/9] Implement requested minor changes --- ts/state/ducks/search.ts | 2 +- ts/types/Search.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index 6064cb66d..56eb7b90d 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -175,7 +175,7 @@ function filterMessages( contacts: Array ) { let filteredMessages = messages; - if (filters.from !== null && filters.from.length > 0) { + if (filters.from && filters.from.length > 0) { if (filters.from === '@me') { filteredMessages = filteredMessages.filter(message => message.sent); } else { diff --git a/ts/types/Search.ts b/ts/types/Search.ts index 990372434..b24914d8e 100644 --- a/ts/types/Search.ts +++ b/ts/types/Search.ts @@ -7,7 +7,7 @@ export type SearchOptions = { export type AdvancedSearchOptions = { query: string; - from: string; + from?: string; before: number; after: number; }; From 366acae1cd493e2cdaa5355b9772db5e40679039 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 10 Mar 2020 06:58:36 +0100 Subject: [PATCH 8/9] Minor Fix check if from is invalid not just null --- ts/state/ducks/search.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index 56eb7b90d..37af10c04 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -112,7 +112,7 @@ async function doSearch( if (isAdvancedQuery) { let senderFilter: Array = []; if ( - advancedSearchOptions.from !== null && + advancedSearchOptions.from && advancedSearchOptions.from.length > 0 ) { const senderFilterQuery = await queryConversationsAndContacts( From 20feb23017e22318a24b5e5740da5c1ab6bba5e0 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 10 Mar 2020 07:07:23 +0100 Subject: [PATCH 9/9] small lint fix in search.ts --- ts/state/ducks/search.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ts/state/ducks/search.ts b/ts/state/ducks/search.ts index 37af10c04..11eb2eade 100644 --- a/ts/state/ducks/search.ts +++ b/ts/state/ducks/search.ts @@ -111,10 +111,7 @@ async function doSearch( if (isAdvancedQuery) { let senderFilter: Array = []; - if ( - advancedSearchOptions.from && - advancedSearchOptions.from.length > 0 - ) { + if (advancedSearchOptions.from && advancedSearchOptions.from.length > 0) { const senderFilterQuery = await queryConversationsAndContacts( advancedSearchOptions.from, options