fix link highlighting with mention present (#1544)

This commit is contained in:
Eric Bailey 2023-09-27 11:15:50 -05:00 committed by GitHub
parent 6d4ad59416
commit b030d94a64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 80 deletions

View file

@ -17,6 +17,7 @@ import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
import {isUriImage, blobToDataUri} from 'lib/media/util'
import {Emoji} from './web/EmojiPicker.web'
import {LinkDecorator} from './web/LinkDecorator'
import {generateJSON} from '@tiptap/html'
export interface TextInputRef {
focus: () => void
@ -52,6 +53,26 @@ export const TextInput = React.forwardRef(function TextInputImpl(
ref,
) {
const modeClass = useColorSchemeStyle('ProseMirror-light', 'ProseMirror-dark')
const extensions = React.useMemo(
() => [
Document,
LinkDecorator,
Mention.configure({
HTMLAttributes: {
class: 'mention',
},
suggestion: createSuggestion({autocompleteView}),
}),
Paragraph,
Placeholder.configure({
placeholder,
}),
Text,
History,
Hardbreak,
],
[autocompleteView, placeholder],
)
React.useEffect(() => {
textInputWebEmitter.addListener('publish', onPressPublish)
@ -68,23 +89,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
const editor = useEditor(
{
extensions: [
Document,
LinkDecorator,
Mention.configure({
HTMLAttributes: {
class: 'mention',
},
suggestion: createSuggestion({autocompleteView}),
}),
Paragraph,
Placeholder.configure({
placeholder,
}),
Text,
History,
Hardbreak,
],
extensions,
editorProps: {
attributes: {
class: modeClass,
@ -107,7 +112,7 @@ export const TextInput = React.forwardRef(function TextInputImpl(
}
},
},
content: textToEditorJson(richtext.text.toString()),
content: generateJSON(richtext.text.toString(), extensions),
autofocus: 'end',
editable: true,
injectCSS: true,
@ -182,61 +187,6 @@ function editorJsonToText(json: JSONContent): string {
return text
}
function textToEditorJson(text: string): JSONContent {
if (text === '' || text.length === 0) {
return {
text: '',
}
}
const lines = text.split('\n')
const docContent: JSONContent[] = []
for (const line of lines) {
if (line.trim() === '') {
continue // skip empty lines
}
const paragraphContent: JSONContent[] = []
let position = 0
while (position < line.length) {
if (line[position] === '@') {
// Handle mentions
let endPosition = position + 1
while (endPosition < line.length && /\S/.test(line[endPosition])) {
endPosition++
}
const mentionId = line.substring(position + 1, endPosition)
paragraphContent.push({
type: 'mention',
attrs: {id: mentionId},
})
position = endPosition
} else {
// Handle regular text
let endPosition = line.indexOf('@', position)
if (endPosition === -1) endPosition = line.length
paragraphContent.push({
type: 'text',
text: line.substring(position, endPosition),
})
position = endPosition
}
}
docContent.push({
type: 'paragraph',
content: paragraphContent,
})
}
return {
type: 'doc',
content: docContent,
}
}
const styles = StyleSheet.create({
container: {
flex: 1,

View file

@ -16,7 +16,6 @@
import {Mark} from '@tiptap/core'
import {Plugin, PluginKey} from '@tiptap/pm/state'
import {findChildren} from '@tiptap/core'
import {Node as ProsemirrorNode} from '@tiptap/pm/model'
import {Decoration, DecorationSet} from '@tiptap/pm/view'
import {isValidDomain} from 'lib/strings/url-helpers'
@ -36,20 +35,20 @@ export const LinkDecorator = Mark.create({
function getDecorations(doc: ProsemirrorNode) {
const decorations: Decoration[] = []
findChildren(doc, node => node.type.name === 'paragraph').forEach(
paragraphNode => {
const textContent = paragraphNode.node.textContent
doc.descendants((node, pos) => {
if (node.isText && node.text) {
const textContent = node.textContent
// links
iterateUris(textContent, (from, to) => {
decorations.push(
Decoration.inline(paragraphNode.pos + from, paragraphNode.pos + to, {
Decoration.inline(pos + from, pos + to, {
class: 'autolink',
}),
)
})
},
)
}
})
return DecorationSet.create(doc, decorations)
}