mirror of
https://github.com/tooot-app/app
synced 2025-04-25 07:28:41 +02:00
Fix fake external tag as link
This commit is contained in:
parent
88323a1552
commit
7db153f2ae
@ -80,7 +80,7 @@ const Button: React.FC<Props> = ({
|
|||||||
<>
|
<>
|
||||||
<Feather
|
<Feather
|
||||||
name={content as any}
|
name={content as any}
|
||||||
size={StyleConstants.Font.Size[size] * (size === 'M' ? 1 : 1.5)}
|
size={StyleConstants.Font.Size[size] * (size === 'L' ? 1.25 : 1)}
|
||||||
color={colorContent}
|
color={colorContent}
|
||||||
style={{ opacity: loading ? 0 : 1 }}
|
style={{ opacity: loading ? 0 : 1 }}
|
||||||
testID='icon'
|
testID='icon'
|
||||||
@ -95,7 +95,7 @@ const Button: React.FC<Props> = ({
|
|||||||
style={{
|
style={{
|
||||||
color: colorContent,
|
color: colorContent,
|
||||||
fontSize:
|
fontSize:
|
||||||
StyleConstants.Font.Size[size] * (size === 'M' ? 1 : 1.5),
|
StyleConstants.Font.Size[size] * (size === 'L' ? 1.25 : 1),
|
||||||
fontWeight: destructive
|
fontWeight: destructive
|
||||||
? StyleConstants.Font.Weight.Bold
|
? StyleConstants.Font.Weight.Bold
|
||||||
: undefined,
|
: undefined,
|
||||||
|
@ -8,6 +8,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
|||||||
import { Feather } from '@expo/vector-icons'
|
import { Feather } from '@expo/vector-icons'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import openLink from '@root/utils/openLink'
|
import openLink from '@root/utils/openLink'
|
||||||
|
import layoutAnimation from '@root/utils/styles/layoutAnimation'
|
||||||
|
|
||||||
// Prevent going to the same hashtag multiple times
|
// Prevent going to the same hashtag multiple times
|
||||||
const renderNode = ({
|
const renderNode = ({
|
||||||
@ -17,6 +18,7 @@ const renderNode = ({
|
|||||||
size,
|
size,
|
||||||
navigation,
|
navigation,
|
||||||
mentions,
|
mentions,
|
||||||
|
tags,
|
||||||
showFullLink
|
showFullLink
|
||||||
}: {
|
}: {
|
||||||
theme: any
|
theme: any
|
||||||
@ -25,6 +27,7 @@ const renderNode = ({
|
|||||||
size: 'M' | 'L'
|
size: 'M' | 'L'
|
||||||
navigation: any
|
navigation: any
|
||||||
mentions?: Mastodon.Mention[]
|
mentions?: Mastodon.Mention[]
|
||||||
|
tags?: Mastodon.Tag[]
|
||||||
showFullLink: boolean
|
showFullLink: boolean
|
||||||
}) => {
|
}) => {
|
||||||
if (node.name == 'a') {
|
if (node.name == 'a') {
|
||||||
@ -75,6 +78,8 @@ const renderNode = ({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const domain = href.split(new RegExp(/:\/\/(.[^\/]+)/))
|
const domain = href.split(new RegExp(/:\/\/(.[^\/]+)/))
|
||||||
|
const content = node.children && node.children[0].data
|
||||||
|
const shouldBeTag = tags && tags.filter(tag => `#${tag.name}` === content)
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
key={index}
|
key={index}
|
||||||
@ -82,14 +87,24 @@ const renderNode = ({
|
|||||||
color: theme.blue,
|
color: theme.blue,
|
||||||
fontSize: StyleConstants.Font.Size[size]
|
fontSize: StyleConstants.Font.Size[size]
|
||||||
}}
|
}}
|
||||||
onPress={async () => await openLink(href)}
|
onPress={async () =>
|
||||||
|
!shouldBeTag
|
||||||
|
? await openLink(href)
|
||||||
|
: navigation.push('Screen-Shared-Hashtag', {
|
||||||
|
hashtag: content.substring(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Feather
|
{!shouldBeTag ? (
|
||||||
name='external-link'
|
<>
|
||||||
size={StyleConstants.Font.Size[size]}
|
<Feather
|
||||||
color={theme.blue}
|
name='external-link'
|
||||||
/>{' '}
|
size={StyleConstants.Font.Size[size]}
|
||||||
{showFullLink ? href : domain[1]}
|
color={theme.blue}
|
||||||
|
/>{' '}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{content || (showFullLink ? href : domain[1])}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -107,6 +122,7 @@ export interface Props {
|
|||||||
size?: 'M' | 'L'
|
size?: 'M' | 'L'
|
||||||
emojis?: Mastodon.Emoji[]
|
emojis?: Mastodon.Emoji[]
|
||||||
mentions?: Mastodon.Mention[]
|
mentions?: Mastodon.Mention[]
|
||||||
|
tags?: Mastodon.Tag[]
|
||||||
showFullLink?: boolean
|
showFullLink?: boolean
|
||||||
numberOfLines?: number
|
numberOfLines?: number
|
||||||
expandHint?: string
|
expandHint?: string
|
||||||
@ -117,6 +133,7 @@ const ParseContent: React.FC<Props> = ({
|
|||||||
size = 'M',
|
size = 'M',
|
||||||
emojis,
|
emojis,
|
||||||
mentions,
|
mentions,
|
||||||
|
tags,
|
||||||
showFullLink = false,
|
showFullLink = false,
|
||||||
numberOfLines = 10,
|
numberOfLines = 10,
|
||||||
expandHint = '全文'
|
expandHint = '全文'
|
||||||
@ -133,6 +150,7 @@ const ParseContent: React.FC<Props> = ({
|
|||||||
size,
|
size,
|
||||||
navigation,
|
navigation,
|
||||||
mentions,
|
mentions,
|
||||||
|
tags,
|
||||||
showFullLink
|
showFullLink
|
||||||
}),
|
}),
|
||||||
[]
|
[]
|
||||||
@ -180,7 +198,7 @@ const ParseContent: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Text
|
<Text
|
||||||
style={{ lineHeight, color: theme.primary }}
|
style={{ lineHeight, color: theme.primary, overflow: 'hidden' }}
|
||||||
children={children}
|
children={children}
|
||||||
numberOfLines={calNumberOfLines}
|
numberOfLines={calNumberOfLines}
|
||||||
onLayout={({ nativeEvent }) => {
|
onLayout={({ nativeEvent }) => {
|
||||||
@ -200,6 +218,7 @@ const ParseContent: React.FC<Props> = ({
|
|||||||
{allowExpand && (
|
{allowExpand && (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
|
layoutAnimation()
|
||||||
setShowAllText(!showAllText)
|
setShowAllText(!showAllText)
|
||||||
}}
|
}}
|
||||||
style={{ marginTop: showAllText ? 0 : -lineHeight * 1.25 }}
|
style={{ marginTop: showAllText ? 0 : -lineHeight * 1.25 }}
|
||||||
|
@ -86,9 +86,6 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(queryKey)
|
|
||||||
console.log('pageIndex', pageIndex)
|
|
||||||
console.log('tootIndex', tootIndex)
|
|
||||||
|
|
||||||
if (pageIndex >= 0 && tootIndex >= 0) {
|
if (pageIndex >= 0 && tootIndex >= 0) {
|
||||||
if (
|
if (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useMemo, useState } from 'react'
|
import React, { useCallback, useMemo, useState } from 'react'
|
||||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
import { Pressable, StyleSheet, View } from 'react-native'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
|
||||||
@ -9,8 +9,8 @@ import { IImageInfo } from 'react-native-image-zoom-viewer/built/image-viewer.ty
|
|||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import AttachmentUnsupported from './Attachment/Unsupported'
|
import AttachmentUnsupported from './Attachment/Unsupported'
|
||||||
import AttachmentAudio from './Attachment/Audio'
|
import AttachmentAudio from './Attachment/Audio'
|
||||||
import { Feather } from '@expo/vector-icons'
|
|
||||||
import layoutAnimation from '@root/utils/styles/layoutAnimation'
|
import layoutAnimation from '@root/utils/styles/layoutAnimation'
|
||||||
|
import Button from '@root/components/Button'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
status: Pick<Mastodon.Status, 'media_attachments' | 'sensitive'>
|
status: Pick<Mastodon.Status, 'media_attachments' | 'sensitive'>
|
||||||
@ -101,39 +101,26 @@ const TimelineAttachment: React.FC<Props> = ({ status, contentWidth }) => {
|
|||||||
{status.sensitive &&
|
{status.sensitive &&
|
||||||
(sensitiveShown ? (
|
(sensitiveShown ? (
|
||||||
<Pressable style={styles.sensitiveBlur}>
|
<Pressable style={styles.sensitiveBlur}>
|
||||||
<Pressable
|
<Button
|
||||||
|
type='text'
|
||||||
|
content='显示敏感内容'
|
||||||
|
overlay
|
||||||
onPress={onPressBlurView}
|
onPress={onPressBlurView}
|
||||||
style={[
|
|
||||||
styles.sensitiveBlurButton,
|
|
||||||
{ backgroundColor: theme.backgroundOverlay }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={[styles.sensitiveText, { color: theme.primaryOverlay }]}
|
|
||||||
>
|
|
||||||
显示敏感内容
|
|
||||||
</Text>
|
|
||||||
</Pressable>
|
|
||||||
</Pressable>
|
|
||||||
) : (
|
|
||||||
<Pressable
|
|
||||||
style={[
|
|
||||||
styles.sensitiveBlurButton,
|
|
||||||
{
|
|
||||||
backgroundColor: theme.backgroundOverlay,
|
|
||||||
position: 'absolute',
|
|
||||||
top: StyleConstants.Spacing.S,
|
|
||||||
left: StyleConstants.Spacing.S
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
onPress={() => setSensitiveShown(!sensitiveShown)}
|
|
||||||
>
|
|
||||||
<Feather
|
|
||||||
name='eye-off'
|
|
||||||
size={StyleConstants.Font.Size.L}
|
|
||||||
color={theme.primaryOverlay}
|
|
||||||
/>
|
/>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
type='icon'
|
||||||
|
content='eye-off'
|
||||||
|
round
|
||||||
|
overlay
|
||||||
|
onPress={() => setSensitiveShown(!sensitiveShown)}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: StyleConstants.Spacing.S,
|
||||||
|
left: StyleConstants.Spacing.S
|
||||||
|
}}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import Button from '@components/Button'
|
||||||
|
import openLink from '@root/utils/openLink'
|
||||||
|
import { StyleConstants } from '@root/utils/styles/constants'
|
||||||
|
import { useTheme } from '@root/utils/styles/ThemeManager'
|
||||||
|
import { Surface } from 'gl-react-expo'
|
||||||
|
import { Blurhash } from 'gl-react-blurhash'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { StyleSheet, Text, View } from 'react-native'
|
import { StyleSheet, Text, View } from 'react-native'
|
||||||
import Button from '@components/Button'
|
|
||||||
import { useTheme } from '@root/utils/styles/ThemeManager'
|
|
||||||
import { StyleConstants } from '@root/utils/styles/constants'
|
|
||||||
import openLink from '@root/utils/openLink'
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
attachment: Mastodon.AttachmentUnknown
|
attachment: Mastodon.AttachmentUnknown
|
||||||
@ -13,12 +15,31 @@ const AttachmentUnsupported: React.FC<Props> = ({ attachment }) => {
|
|||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
return (
|
return (
|
||||||
<View style={styles.base}>
|
<View style={styles.base}>
|
||||||
<Text style={[styles.text, { color: theme.primary }]}>文件不支持</Text>
|
{attachment.blurhash ? (
|
||||||
|
<Surface
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Blurhash hash={attachment.blurhash} />
|
||||||
|
</Surface>
|
||||||
|
) : null}
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.text,
|
||||||
|
{ color: attachment.blurhash ? theme.background : theme.primary }
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
文件不支持
|
||||||
|
</Text>
|
||||||
{attachment.remote_url ? (
|
{attachment.remote_url ? (
|
||||||
<Button
|
<Button
|
||||||
type='text'
|
type='text'
|
||||||
content='尝试远程链接'
|
content='尝试远程链接'
|
||||||
size='S'
|
size='S'
|
||||||
|
overlay
|
||||||
onPress={async () => await openLink(attachment.remote_url!)}
|
onPress={async () => await openLink(attachment.remote_url!)}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
@ -29,6 +50,9 @@ const AttachmentUnsupported: React.FC<Props> = ({ attachment }) => {
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
base: {
|
base: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
flexBasis: '50%',
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
padding: StyleConstants.Spacing.XS / 2,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
},
|
},
|
||||||
|
@ -47,7 +47,8 @@ const AttachmentVideo: React.FC<Props> = ({
|
|||||||
ref={videoPlayer}
|
ref={videoPlayer}
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%'
|
height: '100%',
|
||||||
|
opacity: sensitiveShown ? 0 : 1
|
||||||
}}
|
}}
|
||||||
resizeMode='cover'
|
resizeMode='cover'
|
||||||
usePoster
|
usePoster
|
||||||
|
@ -22,6 +22,8 @@ const TimelineContent: React.FC<Props> = ({
|
|||||||
content={status.spoiler_text}
|
content={status.spoiler_text}
|
||||||
size={highlighted ? 'L' : 'M'}
|
size={highlighted ? 'L' : 'M'}
|
||||||
emojis={status.emojis}
|
emojis={status.emojis}
|
||||||
|
mentions={status.mentions}
|
||||||
|
tags={status.tags}
|
||||||
numberOfLines={999}
|
numberOfLines={999}
|
||||||
/>
|
/>
|
||||||
<View style={{ marginTop: StyleConstants.Font.Size.M }}>
|
<View style={{ marginTop: StyleConstants.Font.Size.M }}>
|
||||||
@ -30,6 +32,7 @@ const TimelineContent: React.FC<Props> = ({
|
|||||||
size={highlighted ? 'L' : 'M'}
|
size={highlighted ? 'L' : 'M'}
|
||||||
emojis={status.emojis}
|
emojis={status.emojis}
|
||||||
mentions={status.mentions}
|
mentions={status.mentions}
|
||||||
|
tags={status.tags}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
expandHint='隐藏内容'
|
expandHint='隐藏内容'
|
||||||
/>
|
/>
|
||||||
@ -41,6 +44,7 @@ const TimelineContent: React.FC<Props> = ({
|
|||||||
size={highlighted ? 'L' : 'M'}
|
size={highlighted ? 'L' : 'M'}
|
||||||
emojis={status.emojis}
|
emojis={status.emojis}
|
||||||
mentions={status.mentions}
|
mentions={status.mentions}
|
||||||
|
tags={status.tags}
|
||||||
numberOfLines={numberOfLines}
|
numberOfLines={numberOfLines}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user