2022-11-12 17:52:50 +01:00
|
|
|
import ComponentAccount from '@components/Account'
|
2021-01-16 00:00:31 +01:00
|
|
|
import GracefullyImage from '@components/GracefullyImage'
|
2021-01-01 16:48:16 +01:00
|
|
|
import openLink from '@components/openLink'
|
2022-05-07 00:52:32 +02:00
|
|
|
import CustomText from '@components/Text'
|
2021-03-21 23:06:53 +01:00
|
|
|
import { useNavigation } from '@react-navigation/native'
|
2023-01-03 23:57:23 +01:00
|
|
|
import { StackNavigationProp } from '@react-navigation/stack'
|
|
|
|
import { urlMatcher } from '@utils/helpers/urlMatcher'
|
|
|
|
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
2022-11-12 17:52:50 +01:00
|
|
|
import { useAccountQuery } from '@utils/queryHooks/account'
|
|
|
|
import { useStatusQuery } from '@utils/queryHooks/status'
|
2020-12-13 14:04:25 +01:00
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
|
|
|
import { useTheme } from '@utils/styles/ThemeManager'
|
2022-12-03 20:47:11 +01:00
|
|
|
import React, { useContext, useEffect, useState } from 'react'
|
2022-12-31 00:07:28 +01:00
|
|
|
import { Pressable, View } from 'react-native'
|
2022-11-12 17:52:50 +01:00
|
|
|
import { Circle } from 'react-native-animated-spinkit'
|
|
|
|
import TimelineDefault from '../Default'
|
2022-12-03 20:47:11 +01:00
|
|
|
import StatusContext from './Context'
|
2020-10-29 14:52:28 +01:00
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
const TimelineCard: React.FC = () => {
|
|
|
|
const { status, spoilerHidden, disableDetails } = useContext(StatusContext)
|
|
|
|
if (!status || !status.card) return null
|
2020-10-31 21:04:46 +01:00
|
|
|
|
2022-04-30 21:47:17 +02:00
|
|
|
const { colors } = useTheme()
|
2023-01-03 23:57:23 +01:00
|
|
|
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
2020-11-28 17:07:30 +01:00
|
|
|
|
2022-11-12 17:52:50 +01:00
|
|
|
const [loading, setLoading] = useState(false)
|
2023-01-03 23:57:23 +01:00
|
|
|
const match = urlMatcher(status.card.url)
|
2022-11-12 17:52:50 +01:00
|
|
|
const [foundStatus, setFoundStatus] = useState<Mastodon.Status>()
|
|
|
|
const [foundAccount, setFoundAccount] = useState<Mastodon.Account>()
|
|
|
|
|
|
|
|
const statusQuery = useStatusQuery({
|
2023-01-03 23:57:23 +01:00
|
|
|
status: match?.status ? { ...match.status, uri: status.card.url } : undefined,
|
2022-11-12 17:52:50 +01:00
|
|
|
options: { enabled: false }
|
|
|
|
})
|
|
|
|
useEffect(() => {
|
2023-01-03 23:57:23 +01:00
|
|
|
if (match?.status) {
|
2022-11-12 17:52:50 +01:00
|
|
|
setLoading(true)
|
2023-01-03 23:57:23 +01:00
|
|
|
statusQuery
|
|
|
|
.refetch()
|
|
|
|
.then(res => {
|
|
|
|
res.data && setFoundStatus(res.data)
|
|
|
|
setLoading(false)
|
|
|
|
})
|
|
|
|
.catch(() => setLoading(false))
|
2022-11-12 17:52:50 +01:00
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
const accountQuery = useAccountQuery({
|
2023-01-03 23:57:23 +01:00
|
|
|
account: match?.account ? { ...match?.account, url: status.card.url } : undefined,
|
2022-11-12 17:52:50 +01:00
|
|
|
options: { enabled: false }
|
|
|
|
})
|
|
|
|
useEffect(() => {
|
2023-01-03 23:57:23 +01:00
|
|
|
if (match?.account) {
|
2022-11-12 17:52:50 +01:00
|
|
|
setLoading(true)
|
2023-01-03 23:57:23 +01:00
|
|
|
accountQuery
|
|
|
|
.refetch()
|
|
|
|
.then(res => {
|
|
|
|
res.data && setFoundAccount(res.data)
|
|
|
|
setLoading(false)
|
|
|
|
})
|
|
|
|
.catch(() => setLoading(false))
|
2022-11-12 17:52:50 +01:00
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
const cardContent = () => {
|
|
|
|
if (loading) {
|
|
|
|
return (
|
|
|
|
<View
|
|
|
|
style={{
|
|
|
|
flex: 1,
|
|
|
|
justifyContent: 'center',
|
|
|
|
alignItems: 'center',
|
|
|
|
paddingVertical: StyleConstants.Spacing.M
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
|
|
|
|
</View>
|
|
|
|
)
|
|
|
|
}
|
2023-01-03 23:57:23 +01:00
|
|
|
if (match?.status && foundStatus) {
|
2022-11-29 23:44:11 +01:00
|
|
|
return <TimelineDefault item={foundStatus} disableDetails disableOnPress />
|
2022-11-12 17:52:50 +01:00
|
|
|
}
|
2023-01-03 23:57:23 +01:00
|
|
|
if (match?.account && foundAccount) {
|
2022-11-29 23:44:11 +01:00
|
|
|
return <ComponentAccount account={foundAccount} />
|
2022-11-12 17:52:50 +01:00
|
|
|
}
|
|
|
|
return (
|
|
|
|
<>
|
2022-12-03 20:47:11 +01:00
|
|
|
{status.card?.image ? (
|
2022-11-12 17:52:50 +01:00
|
|
|
<GracefullyImage
|
2022-12-03 20:47:11 +01:00
|
|
|
uri={{ original: status.card.image }}
|
|
|
|
blurhash={status.card.blurhash}
|
2022-11-12 17:52:50 +01:00
|
|
|
style={{ flexBasis: StyleConstants.Font.LineHeight.M * 5 }}
|
|
|
|
imageStyle={{ borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }}
|
|
|
|
/>
|
|
|
|
) : null}
|
|
|
|
<View style={{ flex: 1, padding: StyleConstants.Spacing.S }}>
|
2022-12-17 23:31:46 +01:00
|
|
|
{status.card?.title.length ? (
|
|
|
|
<CustomText
|
|
|
|
fontStyle='S'
|
|
|
|
numberOfLines={2}
|
|
|
|
style={{
|
|
|
|
marginBottom: StyleConstants.Spacing.XS,
|
|
|
|
color: colors.primaryDefault
|
|
|
|
}}
|
|
|
|
fontWeight='Bold'
|
|
|
|
testID='title'
|
|
|
|
>
|
|
|
|
{status.card.title}
|
|
|
|
</CustomText>
|
|
|
|
) : null}
|
|
|
|
{status.card?.description.length ? (
|
2022-11-12 17:52:50 +01:00
|
|
|
<CustomText
|
|
|
|
fontStyle='S'
|
|
|
|
numberOfLines={1}
|
|
|
|
style={{
|
|
|
|
marginBottom: StyleConstants.Spacing.XS,
|
|
|
|
color: colors.primaryDefault
|
|
|
|
}}
|
|
|
|
testID='description'
|
|
|
|
>
|
2022-12-03 20:47:11 +01:00
|
|
|
{status.card.description}
|
2022-11-12 17:52:50 +01:00
|
|
|
</CustomText>
|
|
|
|
) : null}
|
2022-12-17 23:31:46 +01:00
|
|
|
{status.card?.url.length ? (
|
|
|
|
<CustomText fontStyle='S' numberOfLines={1} style={{ color: colors.secondary }}>
|
|
|
|
{status.card.url}
|
|
|
|
</CustomText>
|
|
|
|
) : null}
|
2022-11-12 17:52:50 +01:00
|
|
|
</View>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
if (spoilerHidden || disableDetails) return null
|
|
|
|
|
2022-04-30 21:47:17 +02:00
|
|
|
return (
|
|
|
|
<Pressable
|
|
|
|
accessible
|
|
|
|
accessibilityRole='link'
|
2022-05-07 00:52:32 +02:00
|
|
|
style={{
|
|
|
|
flex: 1,
|
|
|
|
flexDirection: 'row',
|
|
|
|
marginTop: StyleConstants.Spacing.M,
|
2022-12-31 00:07:28 +01:00
|
|
|
borderWidth: 1,
|
2022-11-12 17:52:50 +01:00
|
|
|
borderRadius: StyleConstants.Spacing.S,
|
2022-05-07 00:52:32 +02:00
|
|
|
overflow: 'hidden',
|
|
|
|
borderColor: colors.border
|
|
|
|
}}
|
2023-01-03 23:57:23 +01:00
|
|
|
onPress={async () => {
|
|
|
|
if (match?.status && foundStatus) {
|
|
|
|
navigation.push('Tab-Shared-Toot', { toot: foundStatus })
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (match?.account && foundAccount) {
|
|
|
|
navigation.push('Tab-Shared-Account', { account: foundAccount })
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
status.card?.url && (await openLink(status.card.url, navigation))
|
|
|
|
}}
|
2022-12-03 20:47:11 +01:00
|
|
|
children={cardContent()}
|
2022-11-12 17:52:50 +01:00
|
|
|
/>
|
2022-04-30 21:47:17 +02:00
|
|
|
)
|
2022-12-03 20:47:11 +01:00
|
|
|
}
|
2020-10-29 14:52:28 +01:00
|
|
|
|
2021-02-27 16:33:54 +01:00
|
|
|
export default TimelineCard
|