tooot/src/components/ParseContent.tsx

139 lines
3.2 KiB
TypeScript
Raw Normal View History

2020-10-28 00:02:37 +01:00
import React from 'react'
import { StyleSheet, Text } from 'react-native'
2020-10-31 21:04:46 +01:00
import HTMLView, { HTMLViewNode } from 'react-native-htmlview'
2020-10-28 00:02:37 +01:00
import { useNavigation } from '@react-navigation/native'
import Emojis from 'src/components/Status/Emojis'
2020-11-05 21:47:50 +01:00
// Prevent going to the same hashtag multiple times
2020-10-31 21:04:46 +01:00
const renderNode = ({
node,
index,
navigation,
mentions,
showFullLink
}: {
node: HTMLViewNode
index: number
navigation: any
2020-10-31 21:04:46 +01:00
mentions?: mastodon.Mention[]
showFullLink: boolean
}) => {
2020-10-28 00:02:37 +01:00
if (node.name == 'a') {
const classes = node.attribs.class
const href = node.attribs.href
if (classes) {
if (classes.includes('hashtag')) {
return (
<Text
key={index}
style={styles.a}
onPress={() => {
const tag = href.split(new RegExp(/\/tag\/(.*)|\/tags\/(.*)/))
2020-11-05 21:47:50 +01:00
navigation.push('Hashtag', {
2020-10-28 00:02:37 +01:00
hashtag: tag[1] || tag[2]
})
}}
>
{node.children[0].data}
{node.children[1]?.children[0].data}
</Text>
)
2020-11-05 21:47:50 +01:00
} else if (classes.includes('mention') && mentions) {
2020-10-28 00:02:37 +01:00
return (
<Text
key={index}
style={styles.a}
onPress={() => {
const username = href.split(new RegExp(/@(.*)/))
const usernameIndex = mentions.findIndex(
m => m.username === username[1]
)
2020-11-05 21:47:50 +01:00
navigation.push('Account', {
2020-10-28 00:02:37 +01:00
id: mentions[usernameIndex].id
})
}}
>
{node.children[0].data}
{node.children[1]?.children[0].data}
</Text>
)
}
} else {
const domain = href.split(new RegExp(/:\/\/(.*?)\//))
return (
<Text
key={index}
style={styles.a}
onPress={() => {
navigation.navigate('Webview', {
uri: href,
domain: domain[1]
})
}}
>
{showFullLink ? href : domain[1]}
</Text>
)
}
}
}
2020-10-31 21:04:46 +01:00
export interface Props {
content: string
emojis?: mastodon.Emoji[]
emojiSize?: number
mentions?: mastodon.Mention[]
showFullLink?: boolean
linesTruncated?: number
}
const ParseContent: React.FC<Props> = ({
2020-10-28 00:02:37 +01:00
content,
emojis,
emojiSize = 14,
mentions,
2020-10-29 14:52:28 +01:00
showFullLink = false,
linesTruncated = 10
2020-10-31 21:04:46 +01:00
}) => {
2020-10-28 00:02:37 +01:00
const navigation = useNavigation()
return (
<HTMLView
value={content}
stylesheet={HTMLstyles}
2020-10-31 21:04:46 +01:00
paragraphBreak=''
2020-10-28 00:02:37 +01:00
renderNode={(node, index) =>
renderNode({ node, index, navigation, mentions, showFullLink })
}
2020-10-31 21:04:46 +01:00
TextComponent={({ children }) =>
2020-11-05 21:47:50 +01:00
emojis && children ? (
<Emojis
content={children.toString()}
emojis={emojis}
dimension={emojiSize}
/>
2020-10-31 21:04:46 +01:00
) : (
<Text>{children}</Text>
)
}
2020-10-29 14:52:28 +01:00
RootComponent={({ children }) => {
return <Text numberOfLines={linesTruncated}>{children}</Text>
}}
2020-10-28 00:02:37 +01:00
/>
)
}
const styles = StyleSheet.create({
a: {
color: 'blue'
}
})
const HTMLstyles = StyleSheet.create({
p: {
marginBottom: 12
}
})
2020-10-31 21:04:46 +01:00
export default ParseContent