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'
|
|
|
|
|
2020-10-29 14:52:28 +01:00
|
|
|
import Emojis from 'src/components/Toot/Emojis'
|
2020-10-28 00:02:37 +01:00
|
|
|
|
2020-10-31 21:04:46 +01:00
|
|
|
const renderNode = ({
|
|
|
|
node,
|
|
|
|
index,
|
|
|
|
navigation,
|
|
|
|
mentions,
|
|
|
|
showFullLink
|
|
|
|
}: {
|
|
|
|
node: HTMLViewNode
|
|
|
|
index: number
|
|
|
|
navigation: object
|
|
|
|
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\/(.*)/))
|
|
|
|
navigation.navigate('Hashtag', {
|
|
|
|
hashtag: tag[1] || tag[2]
|
|
|
|
})
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{node.children[0].data}
|
|
|
|
{node.children[1]?.children[0].data}
|
|
|
|
</Text>
|
|
|
|
)
|
|
|
|
} else if (classes.includes('mention')) {
|
|
|
|
return (
|
|
|
|
<Text
|
|
|
|
key={index}
|
|
|
|
style={styles.a}
|
|
|
|
onPress={() => {
|
|
|
|
const username = href.split(new RegExp(/@(.*)/))
|
|
|
|
const usernameIndex = mentions.findIndex(
|
|
|
|
m => m.username === username[1]
|
|
|
|
)
|
|
|
|
navigation.navigate('Account', {
|
|
|
|
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 }) =>
|
|
|
|
emojis ? (
|
|
|
|
<Emojis content={children} emojis={emojis} dimension={emojiSize} />
|
|
|
|
) : (
|
|
|
|
<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
|