From 3c790d25615c7c5336db5fb030edf17d4e581677 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Fri, 28 Apr 2023 20:55:07 -0400 Subject: [PATCH] MM-52173 Add setting to delay channel autocomplete (#7297) * MM-52173 Add setting to delay channel autocomplete * Remove extra enhancer * Address feedback --- .../autocomplete/channel_mention/index.ts | 42 ++++++++++++++----- app/constants/autocomplete.ts | 3 ++ types/api/config.d.ts | 1 + 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/app/components/autocomplete/channel_mention/index.ts b/app/components/autocomplete/channel_mention/index.ts index 316d42c06..c9f731a42 100644 --- a/app/components/autocomplete/channel_mention/index.ts +++ b/app/components/autocomplete/channel_mention/index.ts @@ -4,26 +4,28 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; import {of as of$} from 'rxjs'; -import {switchMap} from 'rxjs/operators'; +import {map, switchMap} from 'rxjs/operators'; -import {CHANNEL_MENTION_REGEX, CHANNEL_MENTION_SEARCH_REGEX} from '@constants/autocomplete'; +import {CHANNEL_MENTION_REGEX, CHANNEL_MENTION_REGEX_DELAYED, CHANNEL_MENTION_SEARCH_REGEX} from '@constants/autocomplete'; import {observeChannel, queryAllMyChannel, queryChannelsForAutocomplete} from '@queries/servers/channel'; -import {observeCurrentTeamId, observeCurrentUserId} from '@queries/servers/system'; +import {observeConfigBooleanValue, observeCurrentTeamId, observeCurrentUserId} from '@queries/servers/system'; import ChannelMention from './channel_mention'; +import type {Database} from '@nozbe/watermelondb'; import type {WithDatabaseArgs} from '@typings/database/database'; import type ChannelModel from '@typings/database/models/servers/channel'; const getMatchTermForChannelMention = (() => { let lastMatchTerm: string | null = null; let lastValue: string; + let lastMatchPattern: RegExp; let lastIsSearch: boolean; - return (value: string, isSearch: boolean) => { - if (value !== lastValue || isSearch !== lastIsSearch) { - const regex = isSearch ? CHANNEL_MENTION_SEARCH_REGEX : CHANNEL_MENTION_REGEX; - const match = value.match(regex); + return (value: string, matchPattern: RegExp, isSearch: boolean) => { + if (value !== lastValue || matchPattern !== lastMatchPattern || isSearch !== lastIsSearch) { + const match = value.match(matchPattern); lastValue = value; + lastMatchPattern = matchPattern; lastIsSearch = isSearch; if (match) { if (isSearch) { @@ -79,13 +81,31 @@ const withTeamId = withObservables(['teamId', 'channelId'], ({teamId, channelId, }; }); -const enhanced = withObservables(['value', 'isSearch', 'teamId', 'cursorPosition'], ({value, isSearch, teamId, cursorPosition, database}: OwnProps) => { - const matchTerm = getMatchTermForChannelMention(value.substring(0, cursorPosition), isSearch); +function observeMatchPattern(isSearch: boolean, database: Database) { + let matchPattern; - const localChannels = matchTerm === null ? of$(emptyChannelList) : queryChannelsForAutocomplete(database, matchTerm, isSearch, teamId).observe(); + if (isSearch) { + matchPattern = of$(CHANNEL_MENTION_SEARCH_REGEX); + } else { + matchPattern = observeConfigBooleanValue(database, 'DelayChannelAutocomplete').pipe(map((c) => { + return c ? CHANNEL_MENTION_REGEX_DELAYED : CHANNEL_MENTION_REGEX; + })); + } + + return matchPattern; +} + +const enhanced = withObservables(['value', 'isSearch', 'teamId', 'cursorPosition'], ({value, isSearch, teamId, cursorPosition, database}: OwnProps) => { + const matchTerm = observeMatchPattern(isSearch, database).pipe(map((regexp) => { + return getMatchTermForChannelMention(value.substring(0, cursorPosition), regexp, isSearch); + })); + + const localChannels = matchTerm.pipe(switchMap((term) => { + return term === null ? of$(emptyChannelList) : queryChannelsForAutocomplete(database, term, isSearch, teamId).observe(); + })); return { - matchTerm: of$(matchTerm), + matchTerm, localChannels, }; }); diff --git a/app/constants/autocomplete.ts b/app/constants/autocomplete.ts index 102f77f5b..1a696ffec 100644 --- a/app/constants/autocomplete.ts +++ b/app/constants/autocomplete.ts @@ -9,6 +9,8 @@ export const AT_MENTION_SEARCH_REGEX = /\bfrom:\s*(\S*)$/i; export const CHANNEL_MENTION_REGEX = /\B(~([^~\r\n]*))$/i; +export const CHANNEL_MENTION_REGEX_DELAYED = /\B(~([^~\r\n]{2,}))$/i; + export const CHANNEL_MENTION_SEARCH_REGEX = /\b(?:in|channel):\s*(\S*)$/i; export const DATE_MENTION_SEARCH_REGEX = /\b(?:on|before|after):\s*(\S*)$/i; @@ -30,6 +32,7 @@ export default { AT_MENTION_REGEX_GLOBAL, AT_MENTION_SEARCH_REGEX, CHANNEL_MENTION_REGEX, + CHANNEL_MENTION_REGEX_DELAYED, CHANNEL_MENTION_SEARCH_REGEX, CODE_REGEX, DATE_MENTION_SEARCH_REGEX, diff --git a/types/api/config.d.ts b/types/api/config.d.ts index 6586433d8..b2dc94f0b 100644 --- a/types/api/config.d.ts +++ b/types/api/config.d.ts @@ -34,6 +34,7 @@ interface ClientConfig { DataRetentionMessageRetentionDays: string; DefaultClientLocale: string; DefaultTheme: string; + DelayChannelAutocomplete: 'true' | 'false'; DesktopLatestVersion: string; DesktopMinVersion: string; DiagnosticId: string;