From 0296e8411e528ae1c39a5d8231ba2ec89fa2633e Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 4 Oct 2022 10:15:35 -0500 Subject: [PATCH] Fixes to entity extraction --- __tests__/App-test.tsx | 26 ++++++++-------- __tests__/string-utils.ts | 47 +++++++++++++++++++++++++++++ src/state/lib/api.ts | 24 +-------------- src/view/com/modals/ComposePost.tsx | 3 +- src/view/lib/strings.ts | 20 ++++++++++++ 5 files changed, 83 insertions(+), 37 deletions(-) create mode 100644 __tests__/string-utils.ts diff --git a/__tests__/App-test.tsx b/__tests__/App-test.tsx index 47060512..db34ec61 100644 --- a/__tests__/App-test.tsx +++ b/__tests__/App-test.tsx @@ -1,16 +1,16 @@ -/** - * @format - */ +// /** +// * @format +// */ -import 'react-native' -import React from 'react' -import App from '../src/App' +// import 'react-native' +// import React from 'react' +// import App from '../src/App' -// Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer' +// // Note: test renderer must be required after react-native. +// import renderer from 'react-test-renderer' -it('renders correctly', () => { - renderer.act(() => { - renderer.create() - }) -}) +// it('renders correctly', () => { +// renderer.act(() => { +// renderer.create() +// }) +// }) diff --git a/__tests__/string-utils.ts b/__tests__/string-utils.ts new file mode 100644 index 00000000..9e0cd1c3 --- /dev/null +++ b/__tests__/string-utils.ts @@ -0,0 +1,47 @@ +import {extractEntities} from '../src/view/lib/strings' + +describe('extractEntities', () => { + const inputs = [ + 'no mention', + '@start middle end', + 'start @middle end', + 'start middle @end', + '@start @middle @end', + '@full123.test-of-chars', + 'not@right', + '@bad!@#$chars', + '@newline1\n@newline2', + ] + const outputs = [ + undefined, + [{index: [0, 6], type: 'mention', value: 'start'}], + [{index: [6, 13], type: 'mention', value: 'middle'}], + [{index: [13, 17], type: 'mention', value: 'end'}], + [ + {index: [0, 6], type: 'mention', value: 'start'}, + {index: [7, 14], type: 'mention', value: 'middle'}, + {index: [15, 19], type: 'mention', value: 'end'}, + ], + [{index: [0, 22], type: 'mention', value: 'full123.test-of-chars'}], + undefined, + [{index: [0, 4], type: 'mention', value: 'bad'}], + [ + {index: [0, 9], type: 'mention', value: 'newline1'}, + {index: [10, 19], type: 'mention', value: 'newline2'}, + ], + ] + it('correctly handles a set of text inputs', () => { + for (let i = 0; i < inputs.length; i++) { + const input = inputs[i] + const output = extractEntities(input) + expect(output).toEqual(outputs[i]) + if (output) { + for (const outputItem of output) { + expect(input.slice(outputItem.index[0], outputItem.index[1])).toBe( + `@${outputItem.value}`, + ) + } + } + } + }) +}) diff --git a/src/state/lib/api.ts b/src/state/lib/api.ts index db7e2ab2..ad81301f 100644 --- a/src/state/lib/api.ts +++ b/src/state/lib/api.ts @@ -6,14 +6,9 @@ // import {ReactNativeStore} from './auth' import AdxApi from '../../third-party/api' import {ServiceClient} from '../../third-party/api/src/index' -import { - TextSlice, - Entity as Entities, -} from '../../third-party/api/src/types/todo/social/post' import {AdxUri} from '../../third-party/uri' import {RootStoreModel} from '../models/root-store' - -type Entity = Entities[0] +import {extractEntities} from '../../view/lib/strings' export function doPolyfill() { AdxApi.xrpc.fetch = fetchHandler @@ -204,20 +199,3 @@ async function iterateAll( } } while (res.records.length === 100) }*/ - -function extractEntities(text: string): Entity[] | undefined { - let match - let ents: Entity[] = [] - const re = /(^|\s)@([a-zA-Z0-9\.-]+)(\b)/g - while ((match = re.exec(text))) { - ents.push({ - type: 'mention', - value: match[2], - index: [ - match.index + 1, // skip the (^|\s) but include the '@' - match.index + 2 + match[2].length, - ], - }) - } - return ents.length > 0 ? ents : undefined -} diff --git a/src/view/com/modals/ComposePost.tsx b/src/view/com/modals/ComposePost.tsx index e1e7cac5..1d6f9c4e 100644 --- a/src/view/com/modals/ComposePost.tsx +++ b/src/view/com/modals/ComposePost.tsx @@ -1,8 +1,9 @@ -import React, {useMemo, useState} from 'react' +import React, {useEffect, useMemo, useState} from 'react' import {StyleSheet, Text, TouchableOpacity, View} from 'react-native' import {BottomSheetTextInput} from '@gorhom/bottom-sheet' import LinearGradient from 'react-native-linear-gradient' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import * as GetUserFollows from '../../../third-party/api/src/types/todo/social/getUserFollows' import {Autocomplete} from './composer/Autocomplete' import Toast from '../util/Toast' import ProgressCircle from '../util/ProgressCircle' diff --git a/src/view/lib/strings.ts b/src/view/lib/strings.ts index d468a18a..eecec890 100644 --- a/src/view/lib/strings.ts +++ b/src/view/lib/strings.ts @@ -1,4 +1,7 @@ import {AdxUri} from '../../third-party/uri' +import {Entity as Entities} from '../../third-party/api/src/types/todo/social/post' + +type Entity = Entities[0] export function pluralize(n: number, base: string, plural?: string): string { if (n === 1) { @@ -53,3 +56,20 @@ export function ago(date: number | string | Date): string { return new Date(ts).toLocaleDateString() } } + +export function extractEntities(text: string): Entity[] | undefined { + let match + let ents: Entity[] = [] + const re = /(^|\s)(@)([a-zA-Z0-9\.-]+)(\b)/dg + while ((match = re.exec(text))) { + ents.push({ + type: 'mention', + value: match[3], + index: [ + match.indices[2][0], // skip the (^|\s) but include the '@' + match.indices[3][1], + ], + }) + } + return ents.length > 0 ? ents : undefined +}