More precise

This commit is contained in:
Dan Abramov
2024-04-24 06:15:44 +01:00
parent 01be351693
commit 21405442f1
3 changed files with 32 additions and 29 deletions
@@ -134,8 +134,7 @@ export const TextInput = forwardRef(function TextInputImpl(
addLinkCardIfNecessary({ addLinkCardIfNecessary({
uri: feature.uri, uri: feature.uri,
newText, textBeforeCursor: newText.slice(0, cursorLocation),
cursorLocation,
mayBePaste, mayBePaste,
onNewLink, onNewLink,
prevAddedLinks: prevAddedLinks.current, prevAddedLinks: prevAddedLinks.current,
@@ -185,7 +185,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
}, },
onUpdate({editor: editorProp}) { onUpdate({editor: editorProp}) {
const json = editorProp.getJSON() const json = editorProp.getJSON()
const newText = editorJsonToText(json).trimEnd() // Otherwise we have \n\n at the end const newText = editorJsonToText(json)
const mayBePaste = window.event?.type === 'paste' const mayBePaste = window.event?.type === 'paste'
const newRt = new RichText({text: newText}) const newRt = new RichText({text: newText})
@@ -196,15 +196,13 @@ export const TextInput = React.forwardRef(function TextInputImpl(
for (const facet of newRt.facets) { for (const facet of newRt.facets) {
for (const feature of facet.features) { for (const feature of facet.features) {
if (AppBskyRichtextFacet.isLink(feature)) { if (AppBskyRichtextFacet.isLink(feature)) {
// The TipTap editor shows the position as being one character ahead, as if the start index is 1.
// Subtracting 1 from the pos gives us the same behavior as the native impl.
let cursorLocation = editor?.state.selection.$anchor.pos ?? 1
cursorLocation -= 1
addLinkCardIfNecessary({ addLinkCardIfNecessary({
uri: feature.uri, uri: feature.uri,
newText, textBeforeCursor: editorJsonToText(
cursorLocation, editorProp.state.doc
.cut(0, editorProp.state.selection.$anchor.pos)
.toJSON(),
),
mayBePaste, mayBePaste,
onNewLink, onNewLink,
prevAddedLinks: prevAddedLinks.current, prevAddedLinks: prevAddedLinks.current,
@@ -279,15 +277,29 @@ export const TextInput = React.forwardRef(function TextInputImpl(
) )
}) })
function editorJsonToText(json: JSONContent): string { function editorJsonToText(
json: JSONContent,
isLastDocumentChild: boolean = false,
): string {
let text = '' let text = ''
if (json.type === 'doc' || json.type === 'paragraph') { if (json.type === 'doc') {
if (json.content?.length) { if (json.content?.length) {
for (const node of json.content) { for (let i = 0; i < json.content.length; i++) {
const node = json.content[i]
const isLastNode = i === json.content.length - 1
text += editorJsonToText(node, isLastNode)
}
}
} else if (json.type === 'paragraph') {
if (json.content?.length) {
for (let i = 0; i < json.content.length; i++) {
const node = json.content[i]
text += editorJsonToText(node) text += editorJsonToText(node)
} }
} }
text += '\n' if (!isLastDocumentChild) {
text += '\n'
}
} else if (json.type === 'hardBreak') { } else if (json.type === 'hardBreak') {
text += '\n' text += '\n'
} else if (json.type === 'text') { } else if (json.type === 'text') {
@@ -1,32 +1,24 @@
export function addLinkCardIfNecessary({ export function addLinkCardIfNecessary({
uri, uri,
newText, textBeforeCursor,
cursorLocation,
mayBePaste, mayBePaste,
onNewLink, onNewLink,
prevAddedLinks, prevAddedLinks,
endIndex, endIndex,
}: { }: {
uri: string uri: string
newText: string textBeforeCursor: string
cursorLocation: number
mayBePaste: boolean mayBePaste: boolean
onNewLink: (uri: string) => void onNewLink: (uri: string) => void
prevAddedLinks: Set<string> prevAddedLinks: Set<string>
endIndex: number endIndex: number
}) { }) {
newText = newText + ' ' const isLeavingLink =
endIndex === textBeforeCursor.length - 2 ||
(endIndex === textBeforeCursor.length - 1 &&
/[^.,;!?]\s$/m.test(textBeforeCursor))
let toAdd = 2 if (!mayBePaste && !isLeavingLink) {
const backOne = newText.charAt(cursorLocation - 1)
const backTwo = newText.charAt(cursorLocation - 2)
if (backOne === ' ' && /[^.!?]/.test(backTwo)) {
toAdd = 1
}
if (!mayBePaste && endIndex + toAdd !== cursorLocation) {
return return
} }