mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
@ -102,7 +102,11 @@ const GracefullyImage = React.memo(
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={[style, dimension, { backgroundColor: theme.shimmerDefault }]}
|
||||
style={[
|
||||
style,
|
||||
dimension,
|
||||
{ backgroundColor: theme.backgroundOverlayDefault }
|
||||
]}
|
||||
{...(onPress
|
||||
? hidden
|
||||
? { disabled: true }
|
||||
|
@ -121,7 +121,7 @@ const renderNode = ({
|
||||
onPress={async () => {
|
||||
analytics('status_link_press')
|
||||
!disableDetails && !shouldBeTag
|
||||
? await openLink(href)
|
||||
? await openLink(href, navigation)
|
||||
: navigation.push('Tab-Shared-Hashtag', {
|
||||
hashtag: content.substring(1)
|
||||
})
|
||||
|
@ -48,7 +48,6 @@ const TimelineAttachment = React.memo(
|
||||
imageUrls.push({
|
||||
id: attachment.id,
|
||||
url: attachment.url,
|
||||
preview_url: attachment.preview_url,
|
||||
remote_url: attachment.remote_url,
|
||||
width: attachment.meta?.original?.width,
|
||||
height: attachment.meta?.original?.height
|
||||
|
@ -1,6 +1,7 @@
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import openLink from '@components/openLink'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
@ -13,13 +14,14 @@ export interface Props {
|
||||
const TimelineCard = React.memo(
|
||||
({ card }: Props) => {
|
||||
const { theme } = useTheme()
|
||||
const navigation = useNavigation()
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={[styles.card, { borderColor: theme.border }]}
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_card_press')
|
||||
await openLink(card.url)
|
||||
await openLink(card.url, navigation)
|
||||
}}
|
||||
testID='base'
|
||||
>
|
||||
|
@ -1,9 +1,127 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import { NavigationProp, ParamListBase } from '@react-navigation/native'
|
||||
import { navigationRef } from '@root/Screens'
|
||||
import { store } from '@root/store'
|
||||
import { SearchResult } from '@utils/queryHooks/search'
|
||||
import { getInstanceUrl } from '@utils/slices/instancesSlice'
|
||||
import { getSettingsBrowser } from '@utils/slices/settingsSlice'
|
||||
import * as Linking from 'expo-linking'
|
||||
import * as WebBrowser from 'expo-web-browser'
|
||||
|
||||
const openLink = async (url: string) => {
|
||||
// https://social.xmflsct.com/web/statuses/105590085754428765 <- default
|
||||
// https://social.xmflsct.com/@tooot/105590085754428765 <- pretty
|
||||
const matcherStatus = new RegExp(
|
||||
/http[s]?:\/\/(.*)\/(web\/statuses|@.*)\/([0-9]*)/
|
||||
)
|
||||
|
||||
// https://social.xmflsct.com/web/accounts/14195 <- default
|
||||
// https://social.xmflsct.com/@tooot <- pretty
|
||||
const matcherAccount = new RegExp(
|
||||
/http[s]?:\/\/(.*)\/(web\/accounts\/([0-9]*)|@.*)/
|
||||
)
|
||||
|
||||
export let loadingLink = false
|
||||
|
||||
const openLink = async (
|
||||
url: string,
|
||||
navigation?: NavigationProp<
|
||||
ParamListBase,
|
||||
string,
|
||||
Readonly<{
|
||||
key: string
|
||||
index: number
|
||||
routeNames: string[]
|
||||
history?: unknown[] | undefined
|
||||
routes: any[]
|
||||
type: string
|
||||
stale: false
|
||||
}>,
|
||||
{},
|
||||
{}
|
||||
>
|
||||
) => {
|
||||
if (loadingLink) {
|
||||
return
|
||||
}
|
||||
|
||||
const handleNavigation = (
|
||||
page: 'Tab-Shared-Toot' | 'Tab-Shared-Account',
|
||||
options: {}
|
||||
) => {
|
||||
if (navigation) {
|
||||
// @ts-ignore
|
||||
navigation.push(page, options)
|
||||
} else {
|
||||
navigationRef.current?.navigate(page, options)
|
||||
}
|
||||
}
|
||||
|
||||
// If a tooot can be found
|
||||
const matchedStatus = url.match(matcherStatus)
|
||||
if (matchedStatus) {
|
||||
// If the link in current instance
|
||||
const instanceUrl = getInstanceUrl(store.getState())
|
||||
if (matchedStatus[1] === instanceUrl) {
|
||||
handleNavigation('Tab-Shared-Toot', {
|
||||
toot: { id: matchedStatus[3] }
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
loadingLink = true
|
||||
let response
|
||||
try {
|
||||
response = await apiInstance<SearchResult>({
|
||||
version: 'v2',
|
||||
method: 'get',
|
||||
url: 'search',
|
||||
params: { type: 'statuses', q: url, limit: 1, resolve: true }
|
||||
})
|
||||
} catch {}
|
||||
if (response && response.body && response.body.statuses.length) {
|
||||
handleNavigation('Tab-Shared-Toot', {
|
||||
toot: response.body.statuses[0]
|
||||
})
|
||||
loadingLink = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// If an account can be found
|
||||
const matchedAccount = url.match(matcherAccount)
|
||||
console.log(matchedAccount)
|
||||
if (matchedAccount) {
|
||||
// If the link in current instance
|
||||
const instanceUrl = getInstanceUrl(store.getState())
|
||||
if (matchedAccount[1] === instanceUrl) {
|
||||
if (matchedAccount[3] && matchedAccount[3].match(/[0-9]*/)) {
|
||||
handleNavigation('Tab-Shared-Account', {
|
||||
account: { id: matchedAccount[3] }
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
loadingLink = true
|
||||
let response
|
||||
try {
|
||||
response = await apiInstance<SearchResult>({
|
||||
version: 'v2',
|
||||
method: 'get',
|
||||
url: 'search',
|
||||
params: { type: 'accounts', q: url, limit: 1, resolve: true }
|
||||
})
|
||||
} catch {}
|
||||
if (response && response.body && response.body.accounts.length) {
|
||||
handleNavigation('Tab-Shared-Account', {
|
||||
account: response.body.accounts[0]
|
||||
})
|
||||
loadingLink = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
loadingLink = false
|
||||
switch (getSettingsBrowser(store.getState())) {
|
||||
case 'internal':
|
||||
await WebBrowser.openBrowserAsync(url, {
|
||||
|
Reference in New Issue
Block a user