Fixes to entity extraction

zio/stable
Paul Frazee 2022-10-04 10:15:35 -05:00
parent 195d2f7d2b
commit 0296e8411e
5 changed files with 83 additions and 37 deletions

View File

@ -1,16 +1,16 @@
/** // /**
* @format // * @format
*/ // */
import 'react-native' // import 'react-native'
import React from 'react' // import React from 'react'
import App from '../src/App' // import App from '../src/App'
// Note: test renderer must be required after react-native. // // Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer' // import renderer from 'react-test-renderer'
it('renders correctly', () => { // it('renders correctly', () => {
renderer.act(() => { // renderer.act(() => {
renderer.create(<App />) // renderer.create(<App />)
}) // })
}) // })

View File

@ -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}`,
)
}
}
}
})
})

View File

@ -6,14 +6,9 @@
// import {ReactNativeStore} from './auth' // import {ReactNativeStore} from './auth'
import AdxApi from '../../third-party/api' import AdxApi from '../../third-party/api'
import {ServiceClient} from '../../third-party/api/src/index' 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 {AdxUri} from '../../third-party/uri'
import {RootStoreModel} from '../models/root-store' import {RootStoreModel} from '../models/root-store'
import {extractEntities} from '../../view/lib/strings'
type Entity = Entities[0]
export function doPolyfill() { export function doPolyfill() {
AdxApi.xrpc.fetch = fetchHandler AdxApi.xrpc.fetch = fetchHandler
@ -204,20 +199,3 @@ async function iterateAll(
} }
} while (res.records.length === 100) } 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
}

View File

@ -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 {StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import {BottomSheetTextInput} from '@gorhom/bottom-sheet' import {BottomSheetTextInput} from '@gorhom/bottom-sheet'
import LinearGradient from 'react-native-linear-gradient' import LinearGradient from 'react-native-linear-gradient'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 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 {Autocomplete} from './composer/Autocomplete'
import Toast from '../util/Toast' import Toast from '../util/Toast'
import ProgressCircle from '../util/ProgressCircle' import ProgressCircle from '../util/ProgressCircle'

View File

@ -1,4 +1,7 @@
import {AdxUri} from '../../third-party/uri' 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 { export function pluralize(n: number, base: string, plural?: string): string {
if (n === 1) { if (n === 1) {
@ -53,3 +56,20 @@ export function ago(date: number | string | Date): string {
return new Date(ts).toLocaleDateString() 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
}