mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Using new text component
Need to use global accessibility checks rather than per text component which is not efficient
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { RootStackParamList } from '@utils/navigation/navigators'
|
||||
@ -13,7 +14,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
import { useQueryClient } from 'react-query'
|
||||
|
||||
export interface Props {
|
||||
@ -185,7 +186,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
{status.replies_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: colors.secondary,
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
@ -193,7 +194,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{status.replies_count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</>
|
||||
),
|
||||
@ -213,7 +214,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
{status.reblogs_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: color(status.reblogged),
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
@ -221,7 +222,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{status.reblogs_count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
@ -236,7 +237,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
{status.favourites_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
style={{
|
||||
color: color(status.favourited),
|
||||
fontSize: StyleConstants.Font.Size.M,
|
||||
@ -245,7 +246,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{status.favourites_count}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
@ -269,7 +270,7 @@ const TimelineActions: React.FC<Props> = ({
|
||||
: StyleConstants.Avatar.M + StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
<View style={styles.actions}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Pressable
|
||||
{...(highlighted
|
||||
? {
|
||||
@ -334,9 +335,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
actions: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
action: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
|
@ -1,11 +1,12 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
|
||||
@ -27,10 +28,14 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.base,
|
||||
{ aspectRatio: attachmentAspectRatio({ total, index }) }
|
||||
]}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexBasis: '50%',
|
||||
padding: StyleConstants.Spacing.XS / 2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
aspectRatio: attachmentAspectRatio({ total, index })
|
||||
}}
|
||||
>
|
||||
{attachment.blurhash ? (
|
||||
<Blurhash
|
||||
@ -44,18 +49,18 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
) : null}
|
||||
{!sensitiveShown ? (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
styles.text,
|
||||
{
|
||||
color: attachment.blurhash
|
||||
? colors.backgroundDefault
|
||||
: colors.primaryDefault
|
||||
}
|
||||
]}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
color: attachment.blurhash
|
||||
? colors.backgroundDefault
|
||||
: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('shared.attachment.unsupported.text')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{attachment.remote_url ? (
|
||||
<Button
|
||||
type='text'
|
||||
@ -74,19 +79,4 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flex: 1,
|
||||
flexBasis: '50%',
|
||||
padding: StyleConstants.Spacing.XS / 2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
text: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
textAlign: 'center',
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default AttachmentUnsupported
|
||||
|
@ -1,11 +1,12 @@
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
card: Pick<
|
||||
@ -22,7 +23,16 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||
<Pressable
|
||||
accessible
|
||||
accessibilityRole='link'
|
||||
style={[styles.card, { borderColor: colors.border }]}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: StyleConstants.Font.LineHeight.M * 5,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
overflow: 'hidden',
|
||||
borderColor: colors.border
|
||||
}}
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_card_press')
|
||||
await openLink(card.url, navigation)
|
||||
@ -33,71 +43,46 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||
<GracefullyImage
|
||||
uri={{ original: card.image }}
|
||||
blurhash={card.blurhash}
|
||||
style={styles.left}
|
||||
imageStyle={styles.image}
|
||||
style={{ flexBasis: StyleConstants.Font.LineHeight.M * 5 }}
|
||||
imageStyle={{ borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }}
|
||||
/>
|
||||
) : null}
|
||||
<View style={styles.right}>
|
||||
<Text
|
||||
<View style={{ flex: 1, padding: StyleConstants.Spacing.S }}>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
numberOfLines={2}
|
||||
style={[styles.rightTitle, { color: colors.primaryDefault }]}
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
testID='title'
|
||||
>
|
||||
{card.title}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{card.description ? (
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
numberOfLines={1}
|
||||
style={[styles.rightDescription, { color: colors.primaryDefault }]}
|
||||
style={{
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
testID='description'
|
||||
>
|
||||
{card.description}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
numberOfLines={1}
|
||||
style={[styles.rightLink, { color: colors.secondary }]}
|
||||
style={{ color: colors.secondary }}
|
||||
>
|
||||
{card.url}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</Pressable>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: StyleConstants.Font.LineHeight.M * 5,
|
||||
marginTop: StyleConstants.Spacing.M,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderRadius: 6,
|
||||
overflow: 'hidden'
|
||||
},
|
||||
left: {
|
||||
flexBasis: StyleConstants.Font.LineHeight.M * 5
|
||||
},
|
||||
image: {
|
||||
borderTopLeftRadius: 6,
|
||||
borderBottomLeftRadius: 6
|
||||
},
|
||||
right: {
|
||||
flex: 1,
|
||||
padding: StyleConstants.Spacing.S
|
||||
},
|
||||
rightTitle: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.XS,
|
||||
fontWeight: StyleConstants.Font.Weight.Bold
|
||||
},
|
||||
rightDescription: {
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginBottom: StyleConstants.Spacing.XS
|
||||
},
|
||||
rightLink: {
|
||||
...StyleConstants.FontStyle.S
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelineCard
|
||||
|
@ -1,4 +1,5 @@
|
||||
import analytics from '@components/analytics'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
@ -7,7 +8,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
status: Pick<
|
||||
@ -37,7 +38,7 @@ const TimelineFeedback = React.memo(
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
{status.reblogs_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.reblogged_by.accessibilityLabel',
|
||||
{
|
||||
@ -64,10 +65,10 @@ const TimelineFeedback = React.memo(
|
||||
{t('shared.actionsUsers.reblogged_by.text', {
|
||||
count: status.reblogs_count
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
{status.favourites_count > 0 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.favourited_by.accessibilityLabel',
|
||||
{
|
||||
@ -94,12 +95,12 @@ const TimelineFeedback = React.memo(
|
||||
{t('shared.actionsUsers.favourited_by.text', {
|
||||
count: status.favourites_count
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</View>
|
||||
<View>
|
||||
{data && data.length > 1 ? (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.history.accessibilityLabel',
|
||||
{
|
||||
@ -121,7 +122,7 @@ const TimelineFeedback = React.memo(
|
||||
{t('shared.actionsUsers.history.text', {
|
||||
count: data.length - 1
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null}
|
||||
</View>
|
||||
</View>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { store } from '@root/store'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { getInstance, getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||
@ -6,7 +7,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import htmlparser2 from 'htmlparser2-without-node-native'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
const TimelineFiltered = React.memo(
|
||||
() => {
|
||||
@ -15,9 +16,9 @@ const TimelineFiltered = React.memo(
|
||||
|
||||
return (
|
||||
<View style={{ backgroundColor: colors.backgroundDefault }}>
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.secondary,
|
||||
textAlign: 'center',
|
||||
paddingVertical: StyleConstants.Spacing.S,
|
||||
@ -25,7 +26,7 @@ const TimelineFiltered = React.memo(
|
||||
}}
|
||||
>
|
||||
{t('shared.filtered')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
|
@ -1,9 +1,9 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
queryKey?: QueryKeyTimeline
|
||||
@ -22,15 +22,15 @@ const TimelineFullConversation = React.memo(
|
||||
status.mentions.filter(
|
||||
mention => mention.id !== status.in_reply_to_account_id
|
||||
).length) ? (
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.S,
|
||||
color: colors.blue,
|
||||
marginTop: StyleConstants.Spacing.S
|
||||
}}
|
||||
>
|
||||
{t('shared.fullConversation')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null
|
||||
},
|
||||
() => true
|
||||
|
@ -2,6 +2,7 @@ import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
QueryKeyTimeline,
|
||||
useTimelineMutation
|
||||
@ -10,7 +11,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, Text, View } from 'react-native'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import { useQueryClient } from 'react-query'
|
||||
import HeaderSharedCreated from './HeaderShared/Created'
|
||||
import HeaderSharedMuted from './HeaderShared/Muted'
|
||||
@ -20,22 +21,22 @@ const Names = ({ accounts }: { accounts: Mastodon.Account[] }) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<Text
|
||||
<CustomText
|
||||
numberOfLines={1}
|
||||
style={{ ...StyleConstants.FontStyle.M, color: colors.secondary }}
|
||||
>
|
||||
<Text>{t('shared.header.conversation.withAccounts')}</Text>
|
||||
<CustomText>{t('shared.header.conversation.withAccounts')}</CustomText>
|
||||
{accounts.map((account, index) => (
|
||||
<Text key={account.id} numberOfLines={1}>
|
||||
<CustomText key={account.id} numberOfLines={1}>
|
||||
{index !== 0 ? t('common:separator') : undefined}
|
||||
<ParseEmojis
|
||||
content={account.display_name || account.username}
|
||||
emojis={account.emojis}
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
))}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import CustomText from '@components/Text'
|
||||
import { ParseEmojis } from '@root/components/Parse'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
account: Mastodon.Account
|
||||
@ -16,13 +17,13 @@ const HeaderSharedAccount = React.memo(
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
{withoutName ? null : (
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityHint={t(
|
||||
'shared.header.shared.account.name.accessibilityHint'
|
||||
)}
|
||||
style={styles.name}
|
||||
style={{ marginRight: StyleConstants.Spacing.XS }}
|
||||
numberOfLines={1}
|
||||
>
|
||||
<ParseEmojis
|
||||
@ -30,34 +31,21 @@ const HeaderSharedAccount = React.memo(
|
||||
emojis={account.emojis}
|
||||
fontBold
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
)}
|
||||
<Text
|
||||
<CustomText
|
||||
accessibilityHint={t(
|
||||
'shared.header.shared.account.account.accessibilityHint'
|
||||
)}
|
||||
style={[styles.acct, { color: colors.secondary }]}
|
||||
style={{ flexShrink: 1, color: colors.secondary }}
|
||||
numberOfLines={1}
|
||||
>
|
||||
@{account.acct}
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
name: {
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
},
|
||||
acct: {
|
||||
flexShrink: 1
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderSharedAccount
|
||||
|
@ -1,10 +1,10 @@
|
||||
import analytics from '@components/analytics'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
application?: Mastodon.Application
|
||||
@ -16,7 +16,8 @@ const HeaderSharedApplication = React.memo(
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
|
||||
return application && application.name !== 'Web' ? (
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
accessibilityRole='link'
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_header_application_press', {
|
||||
@ -24,24 +25,20 @@ const HeaderSharedApplication = React.memo(
|
||||
})
|
||||
application.website && (await openLink(application.website))
|
||||
}}
|
||||
style={[styles.application, { color: colors.secondary }]}
|
||||
style={{
|
||||
flex: 1,
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
color: colors.secondary
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{t('shared.header.shared.application', {
|
||||
application: application.name
|
||||
})}
|
||||
</Text>
|
||||
</CustomText>
|
||||
) : null
|
||||
},
|
||||
() => true
|
||||
)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
application: {
|
||||
flex: 1,
|
||||
...StyleConstants.FontStyle.S,
|
||||
marginLeft: StyleConstants.Spacing.S
|
||||
}
|
||||
})
|
||||
|
||||
export default HeaderSharedApplication
|
||||
|
@ -1,13 +1,13 @@
|
||||
import Icon from '@components/Icon'
|
||||
import RelativeTime from '@components/RelativeTime'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
created_at: Mastodon.Status['created_at']
|
||||
created_at: Mastodon.Status['created_at'] | number
|
||||
edited_at?: Mastodon.Status['edited_at']
|
||||
}
|
||||
|
||||
@ -18,11 +18,9 @@ const HeaderSharedCreated = React.memo(
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
style={{ ...StyleConstants.FontStyle.S, color: colors.secondary }}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
<RelativeTime date={edited_at || created_at} />
|
||||
</Text>
|
||||
</CustomText>
|
||||
{edited_at ? (
|
||||
<Icon
|
||||
accessibilityLabel={t(
|
||||
|
@ -5,6 +5,7 @@ import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import RelativeTime from '@components/RelativeTime'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
MutationVarsTimelineUpdateStatusProperty,
|
||||
QueryKeyTimeline,
|
||||
@ -83,7 +84,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
if (!poll.expired) {
|
||||
if (!sameAccount && !poll.voted) {
|
||||
return (
|
||||
<View style={styles.button}>
|
||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_vote_press')
|
||||
@ -110,7 +111,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<View style={styles.button}>
|
||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_refresh_press')
|
||||
@ -147,19 +148,19 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
const pollExpiration = useMemo(() => {
|
||||
if (poll.expired) {
|
||||
return (
|
||||
<Text style={[styles.expiration, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.poll.meta.expiration.expired')}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
} else {
|
||||
if (poll.expires_at) {
|
||||
return (
|
||||
<Text style={[styles.expiration, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
<Trans
|
||||
i18nKey='componentTimeline:shared.poll.meta.expiration.until'
|
||||
components={[<RelativeTime date={poll.expires_at} />]}
|
||||
/>
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -179,10 +180,17 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
option => option.votes_count
|
||||
)?.votes_count
|
||||
return poll.options.map((option, index) => (
|
||||
<View key={index} style={styles.optionContainer}>
|
||||
<View style={styles.optionContent}>
|
||||
<View
|
||||
key={index}
|
||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||
>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Icon
|
||||
style={styles.optionSelection}
|
||||
style={{
|
||||
paddingTop:
|
||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={
|
||||
`${poll.own_votes?.includes(index) ? 'Check' : ''}${
|
||||
poll.multiple ? 'Square' : 'Circle'
|
||||
@ -193,11 +201,18 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
poll.own_votes?.includes(index) ? colors.blue : colors.disabled
|
||||
}
|
||||
/>
|
||||
<Text style={styles.optionText}>
|
||||
<CustomText style={{ flex: 1 }}>
|
||||
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
||||
</Text>
|
||||
<Text
|
||||
style={[styles.optionPercentage, { color: colors.primaryDefault }]}
|
||||
</CustomText>
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
flexBasis: '20%',
|
||||
textAlign: 'center',
|
||||
color: colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{poll.votes_count
|
||||
? Math.round(
|
||||
@ -207,21 +222,24 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
: 0}
|
||||
%
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={[
|
||||
styles.background,
|
||||
{
|
||||
width: `${Math.round(
|
||||
(option.votes_count / (poll.voters_count || poll.votes_count)) *
|
||||
100
|
||||
)}%`,
|
||||
backgroundColor:
|
||||
option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
height: StyleConstants.Spacing.XS,
|
||||
minWidth: 2,
|
||||
borderTopRightRadius: 10,
|
||||
borderBottomRightRadius: 10,
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
width: `${Math.round(
|
||||
(option.votes_count / (poll.voters_count || poll.votes_count)) *
|
||||
100
|
||||
)}%`,
|
||||
backgroundColor:
|
||||
option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
))
|
||||
@ -230,7 +248,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
return poll.options.map((option, index) => (
|
||||
<Pressable
|
||||
key={index}
|
||||
style={styles.optionContainer}
|
||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_option_press')
|
||||
!allOptions[index] && haptics('Light')
|
||||
@ -253,16 +271,20 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<View style={[styles.optionContent]}>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Icon
|
||||
style={styles.optionSelection}
|
||||
style={{
|
||||
paddingTop:
|
||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={isSelected(index)}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Text style={styles.optionText}>
|
||||
<CustomText style={{ flex: 1 }}>
|
||||
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
||||
</Text>
|
||||
</CustomText>
|
||||
</View>
|
||||
</Pressable>
|
||||
))
|
||||
@ -271,25 +293,32 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
const pollVoteCounts = useMemo(() => {
|
||||
if (poll.voters_count !== null) {
|
||||
return (
|
||||
<Text style={[styles.votes, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.poll.meta.count.voters', { count: poll.voters_count })}
|
||||
{' • '}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
} else if (poll.votes_count !== null) {
|
||||
return (
|
||||
<Text style={[styles.votes, { color: colors.secondary }]}>
|
||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||
{t('shared.poll.meta.count.votes', { count: poll.votes_count })}
|
||||
{' • '}
|
||||
</Text>
|
||||
</CustomText>
|
||||
)
|
||||
}
|
||||
}, [poll.voters_count, poll.votes_count])
|
||||
|
||||
return (
|
||||
<View style={styles.base}>
|
||||
<View style={{ marginTop: StyleConstants.Spacing.M }}>
|
||||
{poll.expired || poll.voted ? pollBodyDisallow : pollBodyAllow}
|
||||
<View style={styles.meta}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginTop: StyleConstants.Spacing.XS
|
||||
}}
|
||||
>
|
||||
{pollButton}
|
||||
{pollVoteCounts}
|
||||
{pollExpiration}
|
||||
@ -298,55 +327,4 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
base: {
|
||||
marginTop: StyleConstants.Spacing.M
|
||||
},
|
||||
optionContainer: {
|
||||
flex: 1,
|
||||
paddingVertical: StyleConstants.Spacing.S
|
||||
},
|
||||
optionContent: {
|
||||
flex: 1,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
optionText: {
|
||||
flex: 1
|
||||
},
|
||||
optionSelection: {
|
||||
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
},
|
||||
optionPercentage: {
|
||||
...StyleConstants.FontStyle.M,
|
||||
alignSelf: 'center',
|
||||
marginLeft: StyleConstants.Spacing.S,
|
||||
flexBasis: '20%',
|
||||
textAlign: 'center'
|
||||
},
|
||||
background: {
|
||||
height: StyleConstants.Spacing.XS,
|
||||
minWidth: 2,
|
||||
borderTopRightRadius: 10,
|
||||
borderBottomRightRadius: 10,
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.S
|
||||
},
|
||||
meta: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginTop: StyleConstants.Spacing.XS
|
||||
},
|
||||
button: {
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
},
|
||||
votes: {
|
||||
...StyleConstants.FontStyle.S
|
||||
},
|
||||
expiration: {
|
||||
...StyleConstants.FontStyle.S
|
||||
}
|
||||
})
|
||||
|
||||
export default TimelinePoll
|
||||
|
@ -1,5 +1,6 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { ParseHTML } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import { useTranslateQuery } from '@utils/queryHooks/translate'
|
||||
import { getSettingsLanguage } from '@utils/slices/settingsSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -7,7 +8,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import * as Localization from 'expo-localization'
|
||||
import React, { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, Text } from 'react-native'
|
||||
import { Pressable } from 'react-native'
|
||||
import { Circle } from 'react-native-animated-spinkit'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
@ -85,9 +86,9 @@ const TimelineTranslate = React.memo(
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
...StyleConstants.FontStyle.M,
|
||||
color:
|
||||
isLoading || isSuccess
|
||||
? colors.secondary
|
||||
@ -106,14 +107,14 @@ const TimelineTranslate = React.memo(
|
||||
source: data?.sourceLanguage
|
||||
})
|
||||
: t('shared.translate.default')}
|
||||
</Text>
|
||||
<Text>
|
||||
</CustomText>
|
||||
<CustomText>
|
||||
{__DEV__
|
||||
? ` Source: ${status.language}; Target: ${
|
||||
Localization.locale || settingsLanguage || 'en'
|
||||
}`
|
||||
: undefined}
|
||||
</Text>
|
||||
</CustomText>
|
||||
{isLoading ? (
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.M}
|
||||
|
Reference in New Issue
Block a user