split text using Graphemer
This commit is contained in:
@@ -13,11 +13,12 @@ import {
|
|||||||
type TextInputSelectionChangeEventData,
|
type TextInputSelectionChangeEventData,
|
||||||
View,
|
View,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
|
import {AppBskyRichtextFacet, RichText, UnicodeString} from '@atproto/api'
|
||||||
import PasteInput, {
|
import PasteInput, {
|
||||||
type PastedFile,
|
type PastedFile,
|
||||||
type PasteInputRef, // @ts-expect-error no types when installing from github
|
type PasteInputRef, // @ts-expect-error no types when installing from github
|
||||||
} from '@mattermost/react-native-paste-input'
|
} from '@mattermost/react-native-paste-input'
|
||||||
|
import Graphemer from 'graphemer'
|
||||||
|
|
||||||
import {MAX_GRAPHEME_LENGTH, POST_IMG_MAX} from '#/lib/constants'
|
import {MAX_GRAPHEME_LENGTH, POST_IMG_MAX} from '#/lib/constants'
|
||||||
import {downloadAndResize} from '#/lib/media/manip'
|
import {downloadAndResize} from '#/lib/media/manip'
|
||||||
@@ -211,13 +212,15 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||||||
return style
|
return style
|
||||||
}, [t, fonts])
|
}, [t, fonts])
|
||||||
|
|
||||||
|
const splitter = useMemo(() => new Graphemer(), [])
|
||||||
const textDecorated = useMemo(() => {
|
const textDecorated = useMemo(() => {
|
||||||
let excess
|
let excess
|
||||||
let truncatedRichtext = richtext
|
|
||||||
if (richtext.graphemeLength > MAX_GRAPHEME_LENGTH) {
|
if (richtext.graphemeLength > MAX_GRAPHEME_LENGTH) {
|
||||||
truncatedRichtext = richtext.clone()
|
const split = splitter.splitGraphemes(richtext.text)
|
||||||
const excessText =
|
const validText = split.slice(0, MAX_GRAPHEME_LENGTH).join('')
|
||||||
truncatedRichtext.unicodeText.slice(MAX_GRAPHEME_LENGTH)
|
const validUnicode = new UnicodeString(validText)
|
||||||
|
const excessText = split.slice(MAX_GRAPHEME_LENGTH).join('')
|
||||||
|
richtext.delete(validUnicode.utf8.byteLength, richtext.length)
|
||||||
excess = (
|
excess = (
|
||||||
<RNText
|
<RNText
|
||||||
key="excess"
|
key="excess"
|
||||||
@@ -229,14 +232,10 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||||||
{excessText}
|
{excessText}
|
||||||
</RNText>
|
</RNText>
|
||||||
)
|
)
|
||||||
truncatedRichtext.delete(
|
|
||||||
MAX_GRAPHEME_LENGTH,
|
|
||||||
truncatedRichtext.graphemeLength,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
let i = 0
|
let i = 0
|
||||||
|
|
||||||
const segments = Array.from(truncatedRichtext.segments()).map(segment => {
|
const segments = Array.from(richtext.segments()).map(segment => {
|
||||||
return (
|
return (
|
||||||
<RNText
|
<RNText
|
||||||
key={i++}
|
key={i++}
|
||||||
@@ -257,7 +256,7 @@ export const TextInput = forwardRef(function TextInputImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return segments
|
return segments
|
||||||
}, [t, richtext, inputTextStyle])
|
}, [t, richtext, inputTextStyle, splitter])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[a.flex_1, a.pl_md, hasRightPadding && a.pr_4xl]}>
|
<View style={[a.flex_1, a.pl_md, hasRightPadding && a.pr_4xl]}>
|
||||||
|
|||||||
Reference in New Issue
Block a user