Use api package regexes

This commit is contained in:
Eric Bailey
2023-10-24 09:49:13 -05:00
parent ee3d1ff40d
commit c5005958f0
7 changed files with 33 additions and 34 deletions
-7
View File
@@ -1,10 +1,3 @@
export const TAG_REGEX =
/(?:^|\s)(#[\p{L}\p{Emoji_Presentation}\p{Emoji_Modifier_Base}\p{Extended_Pictographic}]{1}[\p{L}\p{Emoji_Presentation}\p{Emoji_Modifier_Base}\p{Extended_Pictographic}\d_-]*)/giu
export const LOOSE_TAG_REGEX =
/(?:^|\s)(#[\p{L}\p{Emoji_Presentation}\p{Emoji_Modifier_Base}\p{Extended_Pictographic}]{1}[\p{L}\p{Emoji_Presentation}\p{Emoji_Modifier_Base}\p{Extended_Pictographic}\d_-]*\S*)/giu
export const ENDING_PUNCTUATION_REGEX = /\p{P}+$/gu
export const LEADING_HASH_REGEX = /^#/g
export function sanitize(tagString: string) { export function sanitize(tagString: string) {
return tagString return tagString
.trim() .trim()
+2 -10
View File
@@ -44,7 +44,7 @@ export class TagsAutocompleteModel {
isActive = false isActive = false
query = '' query = ''
searchedTags: string[] = [] searchedTags: string[] = []
profileTags: string[] = ['biology'] profileTags: string[] = []
constructor(public rootStore: RootStoreModel) { constructor(public rootStore: RootStoreModel) {
makeAutoObservable( makeAutoObservable(
@@ -113,15 +113,7 @@ export class TagsAutocompleteModel {
// TODO hook up to search type-ahead // TODO hook up to search type-ahead
async _search() { async _search() {
runInAction(() => { runInAction(() => {
this.searchedTags = [ this.searchedTags = []
'bluesky',
'code',
'coding',
'dev',
'developer',
'development',
'devlife',
]
}) })
} }
} }
+2 -2
View File
@@ -22,8 +22,8 @@ import * as Sheet from 'view/com/sheets/Base'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {ActivityIndicator} from 'react-native' import {ActivityIndicator} from 'react-native'
import {TagInputEntryButton} from './TagInputEntryButton' import {TagInputEntryButton} from './TagInputEntryButton'
import {sanitize} from 'lib/strings/hashtags'
import {uniq} from 'lib/strings/helpers' import {uniq} from 'lib/strings/helpers'
import {sanitizeHashtag} from './util'
export function TagInput({ export function TagInput({
max = 8, max = 8,
@@ -70,7 +70,7 @@ export function TagInput({
const addTagAndReset = React.useCallback( const addTagAndReset = React.useCallback(
(value: string) => { (value: string) => {
const tag = sanitize(value) const tag = sanitizeHashtag(value)
// enforce max hashtag length // enforce max hashtag length
if (tag.length > 0 && tag.length <= 64) { if (tag.length > 0 && tag.length <= 64) {
+2 -2
View File
@@ -22,8 +22,8 @@ import {Text} from 'view/com/util/text/Text'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {TagInputEntryButton} from './TagInputEntryButton' import {TagInputEntryButton} from './TagInputEntryButton'
import {TextInputFocusEventData} from 'react-native' import {TextInputFocusEventData} from 'react-native'
import {sanitize} from 'lib/strings/hashtags'
import {uniq} from 'lib/strings/helpers' import {uniq} from 'lib/strings/helpers'
import {sanitizeHashtag} from './util'
export function TagInput({ export function TagInput({
max = 8, max = 8,
@@ -84,7 +84,7 @@ export function TagInput({
const addTagAndReset = React.useCallback( const addTagAndReset = React.useCallback(
(value: string) => { (value: string) => {
const tag = sanitize(value) const tag = sanitizeHashtag(value)
// enforce max hashtag length // enforce max hashtag length
if (tag.length > 0 && tag.length <= 64) { if (tag.length > 0 && tag.length <= 64) {
+8
View File
@@ -0,0 +1,8 @@
import {TRAILING_PUNCTUATION_REGEX, LEADING_HASH_REGEX} from '@atproto/api'
export function sanitizeHashtag(tagString: string) {
return tagString
.trim()
.replace(LEADING_HASH_REGEX, '')
.replace(TRAILING_PUNCTUATION_REGEX, '')
}
@@ -5,13 +5,13 @@ import {TagsAutocompleteModel} from 'state/models/ui/tags-autocomplete'
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {Text} from 'view/com/util/text/Text' import {Text} from 'view/com/util/text/Text'
import {LEADING_HASH_REGEX, TAG_REGEX} from 'lib/strings/hashtags' import {LEADING_HASH_REGEX, HASHTAG_REGEX} from '@atproto/api'
/** /**
* Loops over matches in the text to find the hashtag under the cursor. * Loops over matches in the text to find the hashtag under the cursor.
*/ */
export function getHashtagAt(text: string, position: number) { export function getHashtagAt(text: string, position: number) {
for (const match of Array.from(text.matchAll(TAG_REGEX))) { for (const match of Array.from(text.matchAll(HASHTAG_REGEX))) {
const {index} = match const {index} = match
const [matchedString, tag] = match const [matchedString, tag] = match
@@ -1,11 +1,15 @@
import { import {
LOOSE_TAG_REGEX, HASHTAG_REGEX_WITH_TRAILING_PUNCTUATION,
ENDING_PUNCTUATION_REGEX, TRAILING_PUNCTUATION_REGEX,
LEADING_HASH_REGEX, LEADING_HASH_REGEX,
} from 'lib/strings/hashtags' } from '@atproto/api'
/**
* This method eventually receives the `query` property from the result of
* `findSuggestionMatch` below.
*/
export function parsePunctuationFromTag(value: string) { export function parsePunctuationFromTag(value: string) {
const reg = ENDING_PUNCTUATION_REGEX const reg = TRAILING_PUNCTUATION_REGEX
const tag = value.replace(reg, '') const tag = value.replace(reg, '')
const punctuation = value.match(reg)?.[0] || '' const punctuation = value.match(reg)?.[0] || ''
@@ -26,25 +30,27 @@ export function findSuggestionMatch({
text: string text: string
cursorPosition: number cursorPosition: number
}) { }) {
const match = Array.from(text.matchAll(LOOSE_TAG_REGEX)).pop() const match = Array.from(
text.matchAll(HASHTAG_REGEX_WITH_TRAILING_PUNCTUATION),
).pop()
if (!match || match.input === undefined || match.index === undefined) { if (!match || match.input === undefined || match.index === undefined) {
return null return null
} }
const startIndex = cursorPosition - text.length const startIndex = cursorPosition - text.length
let [matchedString, looselyMatchedTag] = match let [matchedString, tagWithTrailingPunctuation] = match
const sanitized = looselyMatchedTag const sanitized = tagWithTrailingPunctuation
.replace(ENDING_PUNCTUATION_REGEX, '') .replace(TRAILING_PUNCTUATION_REGEX, '')
.replace(LEADING_HASH_REGEX, '') .replace(LEADING_HASH_REGEX, '')
// one of our hashtag spec rules // one of our hashtag spec rules
if (sanitized.length > 64) return null if (sanitized.length > 64) return null
const from = const from =
startIndex + match.index + matchedString.indexOf(looselyMatchedTag) startIndex + match.index + matchedString.indexOf(tagWithTrailingPunctuation)
const to = from + looselyMatchedTag.length const to = from + tagWithTrailingPunctuation.length
if (from < cursorPosition && to >= cursorPosition) { if (from < cursorPosition && to >= cursorPosition) {
return { return {
@@ -58,7 +64,7 @@ export function findSuggestionMatch({
* *
* We parse out the punctuation later. * We parse out the punctuation later.
*/ */
query: looselyMatchedTag.replace(LEADING_HASH_REGEX, ''), query: tagWithTrailingPunctuation.replace(LEADING_HASH_REGEX, ''),
// raw text string // raw text string
text: matchedString, text: matchedString,
} }