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