mirror of
https://github.com/tooot-app/app
synced 2025-02-21 06:10:54 +01:00
Fixed #60
This commit is contained in:
parent
2620ec52bb
commit
bde6c77cc1
@ -46,7 +46,6 @@
|
|||||||
"expo-firebase-analytics": "~2.6.0",
|
"expo-firebase-analytics": "~2.6.0",
|
||||||
"expo-haptics": "~8.4.0",
|
"expo-haptics": "~8.4.0",
|
||||||
"expo-image-picker": "~9.2.0",
|
"expo-image-picker": "~9.2.0",
|
||||||
"expo-linear-gradient": "~8.4.0",
|
|
||||||
"expo-linking": "~2.0.1",
|
"expo-linking": "~2.0.1",
|
||||||
"expo-localization": "~9.1.0",
|
"expo-localization": "~9.1.0",
|
||||||
"expo-notifications": "~0.8.2",
|
"expo-notifications": "~0.8.2",
|
||||||
|
@ -9,10 +9,9 @@ import { StyleConstants } from '@utils/styles/constants'
|
|||||||
import layoutAnimation from '@utils/styles/layoutAnimation'
|
import layoutAnimation from '@utils/styles/layoutAnimation'
|
||||||
import { adaptiveScale } from '@utils/styles/scaling'
|
import { adaptiveScale } from '@utils/styles/scaling'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import { LinearGradient } from 'expo-linear-gradient'
|
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Platform, Pressable, Text, View } from 'react-native'
|
import { Pressable, Text, View } from 'react-native'
|
||||||
import HTMLView from 'react-native-htmlview'
|
import HTMLView from 'react-native-htmlview'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
@ -164,120 +163,102 @@ export interface Props {
|
|||||||
disableDetails?: boolean
|
disableDetails?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ParseHTML: React.FC<Props> = ({
|
const ParseHTML = React.memo(
|
||||||
content,
|
({
|
||||||
size = 'M',
|
content,
|
||||||
adaptiveSize = false,
|
size = 'M',
|
||||||
emojis,
|
adaptiveSize = false,
|
||||||
mentions,
|
emojis,
|
||||||
tags,
|
mentions,
|
||||||
showFullLink = false,
|
tags,
|
||||||
numberOfLines = 10,
|
showFullLink = false,
|
||||||
expandHint,
|
numberOfLines = 10,
|
||||||
disableDetails = false
|
expandHint,
|
||||||
}) => {
|
disableDetails = false
|
||||||
const adaptiveFontsize = useSelector(getSettingsFontsize)
|
}: Props) => {
|
||||||
const adaptedFontsize = adaptiveScale(
|
const adaptiveFontsize = useSelector(getSettingsFontsize)
|
||||||
StyleConstants.Font.Size[size],
|
const adaptedFontsize = adaptiveScale(
|
||||||
adaptiveSize ? adaptiveFontsize : 0
|
StyleConstants.Font.Size[size],
|
||||||
)
|
adaptiveSize ? adaptiveFontsize : 0
|
||||||
const adaptedLineheight = adaptiveScale(
|
)
|
||||||
StyleConstants.Font.LineHeight[size],
|
const adaptedLineheight = adaptiveScale(
|
||||||
adaptiveSize ? adaptiveFontsize : 0
|
StyleConstants.Font.LineHeight[size],
|
||||||
)
|
adaptiveSize ? adaptiveFontsize : 0
|
||||||
|
)
|
||||||
|
|
||||||
const navigation = useNavigation<
|
const navigation = useNavigation<
|
||||||
StackNavigationProp<Nav.TabLocalStackParamList>
|
StackNavigationProp<Nav.TabLocalStackParamList>
|
||||||
>()
|
>()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { theme } = useTheme()
|
const { mode, theme } = useTheme()
|
||||||
const { t, i18n } = useTranslation('componentParse')
|
const { t, i18n } = useTranslation('componentParse')
|
||||||
if (!expandHint) {
|
if (!expandHint) {
|
||||||
expandHint = t('HTML.defaultHint')
|
expandHint = t('HTML.defaultHint')
|
||||||
}
|
|
||||||
|
|
||||||
const renderNodeCallback = useCallback(
|
|
||||||
(node, index) =>
|
|
||||||
renderNode({
|
|
||||||
routeParams: route.params,
|
|
||||||
theme,
|
|
||||||
node,
|
|
||||||
index,
|
|
||||||
adaptedFontsize,
|
|
||||||
adaptedLineheight,
|
|
||||||
navigation,
|
|
||||||
mentions,
|
|
||||||
tags,
|
|
||||||
showFullLink,
|
|
||||||
disableDetails
|
|
||||||
}),
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
const textComponent = useCallback(({ children }) => {
|
|
||||||
if (children) {
|
|
||||||
return (
|
|
||||||
<ParseEmojis
|
|
||||||
content={children.toString()}
|
|
||||||
emojis={emojis}
|
|
||||||
size={size}
|
|
||||||
adaptiveSize={adaptiveSize}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}, [])
|
|
||||||
const rootComponent = useCallback(
|
|
||||||
({ children }) => {
|
|
||||||
const { t } = useTranslation('componentParse')
|
|
||||||
|
|
||||||
const [expandAllow, setExpandAllow] = useState(false)
|
const renderNodeCallback = useCallback(
|
||||||
const [expanded, setExpanded] = useState(false)
|
(node, index) =>
|
||||||
|
renderNode({
|
||||||
const onTextLayout = useCallback(({ nativeEvent }) => {
|
routeParams: route.params,
|
||||||
switch (Platform.OS) {
|
theme,
|
||||||
case 'ios':
|
node,
|
||||||
if (nativeEvent.lines.length === numberOfLines + 1) {
|
index,
|
||||||
setExpandAllow(true)
|
adaptedFontsize,
|
||||||
}
|
adaptedLineheight,
|
||||||
break
|
navigation,
|
||||||
case 'android':
|
mentions,
|
||||||
if (nativeEvent.lines.length > numberOfLines + 1) {
|
tags,
|
||||||
setExpandAllow(true)
|
showFullLink,
|
||||||
}
|
disableDetails
|
||||||
break
|
}),
|
||||||
}
|
[]
|
||||||
}, [])
|
)
|
||||||
|
const textComponent = useCallback(({ children }) => {
|
||||||
return (
|
if (children) {
|
||||||
<View style={{ overflow: 'hidden' }}>
|
return (
|
||||||
<Text
|
<ParseEmojis
|
||||||
children={children}
|
content={children.toString()}
|
||||||
onTextLayout={onTextLayout}
|
emojis={emojis}
|
||||||
numberOfLines={expanded ? 999 : numberOfLines + 1}
|
size={size}
|
||||||
|
adaptiveSize={adaptiveSize}
|
||||||
/>
|
/>
|
||||||
{expandAllow ? (
|
)
|
||||||
<Pressable
|
} else {
|
||||||
onPress={() => {
|
return null
|
||||||
analytics('status_readmore', { allow: expandAllow, expanded })
|
}
|
||||||
layoutAnimation()
|
}, [])
|
||||||
setExpanded(!expanded)
|
const rootComponent = useCallback(
|
||||||
}}
|
({ children }) => {
|
||||||
style={{
|
const { t } = useTranslation('componentParse')
|
||||||
marginTop: expanded
|
|
||||||
? 0
|
const [expandAllow, setExpandAllow] = useState(false)
|
||||||
: -adaptedLineheight * (numberOfLines === 0 ? 1 : 2)
|
const [expanded, setExpanded] = useState(false)
|
||||||
}}
|
|
||||||
>
|
const onTextLayout = useCallback(({ nativeEvent }) => {
|
||||||
<LinearGradient
|
if (nativeEvent.lines.length >= numberOfLines) {
|
||||||
colors={[
|
setExpandAllow(true)
|
||||||
theme.backgroundGradientStart,
|
}
|
||||||
theme.backgroundGradientEnd
|
}, [])
|
||||||
]}
|
|
||||||
locations={[0, adaptedLineheight / (adaptedFontsize * 5)]}
|
return (
|
||||||
|
<View style={{ overflow: 'hidden' }}>
|
||||||
|
<Text
|
||||||
|
children={children}
|
||||||
|
onTextLayout={onTextLayout}
|
||||||
|
numberOfLines={expanded ? 999 : numberOfLines}
|
||||||
|
/>
|
||||||
|
{expandAllow ? (
|
||||||
|
<Pressable
|
||||||
|
onPress={() => {
|
||||||
|
analytics('status_readmore', { allow: expandAllow, expanded })
|
||||||
|
layoutAnimation()
|
||||||
|
setExpanded(!expanded)
|
||||||
|
}}
|
||||||
style={{
|
style={{
|
||||||
paddingTop: StyleConstants.Font.Size.S * 2,
|
justifyContent: 'center',
|
||||||
paddingBottom: StyleConstants.Font.Size.S
|
marginTop: expanded ? 0 : -adaptedLineheight,
|
||||||
|
minHeight: 44,
|
||||||
|
backgroundColor: theme.background
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
@ -286,29 +267,28 @@ const ParseHTML: React.FC<Props> = ({
|
|||||||
...StyleConstants.FontStyle.S,
|
...StyleConstants.FontStyle.S,
|
||||||
color: theme.primary
|
color: theme.primary
|
||||||
}}
|
}}
|
||||||
>
|
children={t(`HTML.expanded.${expanded.toString()}`, {
|
||||||
{expanded
|
hint: expandHint
|
||||||
? t('HTML.expanded.true', { hint: expandHint })
|
})}
|
||||||
: t('HTML.expanded.false', { hint: expandHint })}
|
/>
|
||||||
</Text>
|
</Pressable>
|
||||||
</LinearGradient>
|
) : null}
|
||||||
</Pressable>
|
</View>
|
||||||
) : null}
|
)
|
||||||
</View>
|
},
|
||||||
)
|
[mode, i18n.language]
|
||||||
},
|
)
|
||||||
[theme, i18n.language]
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HTMLView
|
<HTMLView
|
||||||
value={content}
|
value={content}
|
||||||
TextComponent={textComponent}
|
TextComponent={textComponent}
|
||||||
RootComponent={rootComponent}
|
RootComponent={rootComponent}
|
||||||
renderNode={renderNodeCallback}
|
renderNode={renderNodeCallback}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
|
() => true
|
||||||
|
)
|
||||||
|
|
||||||
// export default ParseHTML
|
export default ParseHTML
|
||||||
export default React.memo(ParseHTML, () => true)
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { ParseHTML } from '@components/Parse'
|
import { ParseHTML } from '@components/Parse'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { View } from 'react-native'
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
status: Mastodon.Status
|
status: Mastodon.Status
|
||||||
@ -24,18 +22,16 @@ const TimelineContent = React.memo(
|
|||||||
<>
|
<>
|
||||||
{status.spoiler_text ? (
|
{status.spoiler_text ? (
|
||||||
<>
|
<>
|
||||||
<View style={{ marginBottom: StyleConstants.Font.Size.M }}>
|
<ParseHTML
|
||||||
<ParseHTML
|
content={status.spoiler_text}
|
||||||
content={status.spoiler_text}
|
size={highlighted ? 'L' : 'M'}
|
||||||
size={highlighted ? 'L' : 'M'}
|
adaptiveSize
|
||||||
adaptiveSize
|
emojis={status.emojis}
|
||||||
emojis={status.emojis}
|
mentions={status.mentions}
|
||||||
mentions={status.mentions}
|
tags={status.tags}
|
||||||
tags={status.tags}
|
numberOfLines={999}
|
||||||
numberOfLines={999}
|
disableDetails={disableDetails}
|
||||||
disableDetails={disableDetails}
|
/>
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<ParseHTML
|
<ParseHTML
|
||||||
content={status.content}
|
content={status.content}
|
||||||
size={highlighted ? 'L' : 'M'}
|
size={highlighted ? 'L' : 'M'}
|
||||||
@ -43,7 +39,7 @@ const TimelineContent = React.memo(
|
|||||||
emojis={status.emojis}
|
emojis={status.emojis}
|
||||||
mentions={status.mentions}
|
mentions={status.mentions}
|
||||||
tags={status.tags}
|
tags={status.tags}
|
||||||
numberOfLines={0}
|
numberOfLines={1}
|
||||||
expandHint={t('shared.content.expandHint')}
|
expandHint={t('shared.content.expandHint')}
|
||||||
disableDetails={disableDetails}
|
disableDetails={disableDetails}
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user