Add support for web links
parent
9d13e05dbf
commit
6e2b7a0b90
|
@ -108,7 +108,7 @@ export const ComposePost = observer(function ComposePost({
|
|||
: undefined
|
||||
|
||||
const textDecorated = useMemo(() => {
|
||||
const re = /(@[a-z0-9\.]*)/gi
|
||||
const re = /(@[a-z0-9\.]*)|(https?:\/\/[\S]+)/gi
|
||||
const segments = []
|
||||
let match
|
||||
let start = 0
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {
|
||||
Linking,
|
||||
StyleProp,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
|
@ -8,6 +9,7 @@ import {
|
|||
ViewStyle,
|
||||
} from 'react-native'
|
||||
import {useStores} from '../../../state'
|
||||
import {RootStoreModel} from '../../../state'
|
||||
import {LinkActionsModel} from '../../../state/models/shell-ui'
|
||||
|
||||
export const Link = observer(function Link({
|
||||
|
@ -23,13 +25,10 @@ export const Link = observer(function Link({
|
|||
}) {
|
||||
const store = useStores()
|
||||
const onPress = () => {
|
||||
store.shell.closeModal() // close any active modals
|
||||
store.nav.navigate(href)
|
||||
handleLink(store, href, false)
|
||||
}
|
||||
const onLongPress = () => {
|
||||
store.shell.closeModal() // close any active modals
|
||||
store.nav.newTab(href, title)
|
||||
// store.shell.openModal(new LinkActionsModel(href, title || href))
|
||||
handleLink(store, href, true)
|
||||
}
|
||||
return (
|
||||
<TouchableOpacity
|
||||
|
@ -55,12 +54,10 @@ export const TextLink = observer(function Link({
|
|||
}) {
|
||||
const store = useStores()
|
||||
const onPress = () => {
|
||||
store.shell.closeModal() // close any active modals
|
||||
store.nav.navigate(href)
|
||||
handleLink(store, href, false)
|
||||
}
|
||||
const onLongPress = () => {
|
||||
store.shell.closeModal() // close any active modals
|
||||
store.nav.newTab(href, title)
|
||||
handleLink(store, href, true)
|
||||
}
|
||||
return (
|
||||
<Text style={style} onPress={onPress} onLongPress={onLongPress}>
|
||||
|
@ -68,3 +65,15 @@ export const TextLink = observer(function Link({
|
|||
</Text>
|
||||
)
|
||||
})
|
||||
|
||||
function handleLink(store: RootStoreModel, href: string, longPress: boolean) {
|
||||
if (href.startsWith('http')) {
|
||||
Linking.openURL(href)
|
||||
} else if (longPress) {
|
||||
store.shell.closeModal() // close any active modals
|
||||
store.nav.newTab(href)
|
||||
} else {
|
||||
store.shell.closeModal() // close any active modals
|
||||
store.nav.navigate(href)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,14 +32,25 @@ export function RichText({
|
|||
if (typeof segment === 'string') {
|
||||
els.push(segment)
|
||||
} else {
|
||||
els.push(
|
||||
<TextLink
|
||||
key={key}
|
||||
text={segment.text}
|
||||
href={`/profile/${segment.entity.value}`}
|
||||
style={[style, s.blue3]}
|
||||
/>,
|
||||
)
|
||||
if (segment.entity.type === 'mention') {
|
||||
els.push(
|
||||
<TextLink
|
||||
key={key}
|
||||
text={segment.text}
|
||||
href={`/profile/${segment.entity.value}`}
|
||||
style={[style, s.blue3]}
|
||||
/>,
|
||||
)
|
||||
} else if (segment.entity.type === 'link') {
|
||||
els.push(
|
||||
<TextLink
|
||||
key={key}
|
||||
text={segment.text}
|
||||
href={segment.entity.value}
|
||||
style={[style, s.blue3]}
|
||||
/>,
|
||||
)
|
||||
}
|
||||
}
|
||||
key++
|
||||
}
|
||||
|
|
|
@ -63,19 +63,36 @@ export function extractEntities(
|
|||
): Entity[] | undefined {
|
||||
let match
|
||||
let ents: Entity[] = []
|
||||
const re = /(^|\s)(@)([a-zA-Z0-9\.-]+)(\b)/dg
|
||||
while ((match = re.exec(text))) {
|
||||
if (knownHandles && !knownHandles.has(match[3])) {
|
||||
continue // not a known handle
|
||||
{
|
||||
// mentions
|
||||
const re = /(^|\s)(@)([a-zA-Z0-9\.-]+)(\b)/dg
|
||||
while ((match = re.exec(text))) {
|
||||
if (knownHandles && !knownHandles.has(match[3])) {
|
||||
continue // not a known handle
|
||||
}
|
||||
ents.push({
|
||||
type: 'mention',
|
||||
value: match[3],
|
||||
index: {
|
||||
start: match.indices[2][0], // skip the (^|\s) but include the '@'
|
||||
end: match.indices[3][1],
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
{
|
||||
// links
|
||||
const re = /(^|\s)(https?:\/\/[\S]+)(\b)/dg
|
||||
while ((match = re.exec(text))) {
|
||||
ents.push({
|
||||
type: 'link',
|
||||
value: match[2],
|
||||
index: {
|
||||
start: match.indices[1][0], // skip the (^|\s) but include the '@'
|
||||
end: match.indices[2][1],
|
||||
},
|
||||
})
|
||||
}
|
||||
ents.push({
|
||||
type: 'mention',
|
||||
value: match[3],
|
||||
index: {
|
||||
start: match.indices[2][0], // skip the (^|\s) but include the '@'
|
||||
end: match.indices[3][1],
|
||||
},
|
||||
})
|
||||
}
|
||||
return ents.length > 0 ? ents : undefined
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue