1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Update translations

This commit is contained in:
Zhiyuan Zheng
2021-01-19 01:13:45 +01:00
parent 5c4f7ce8c7
commit 5a248716bf
79 changed files with 948 additions and 541 deletions

View File

@ -1,4 +1,4 @@
import React, { useRef } from 'react'
import React from 'react'
import { Dimensions, Modal, StyleSheet, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useTheme } from '@utils/styles/ThemeManager'

View File

@ -12,6 +12,7 @@ import {
} from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as Linking from 'expo-linking'
import { debounce } from 'lodash'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -36,7 +37,7 @@ const ComponentInstance: React.FC<Props> = ({
const navigation = useNavigation()
const dispatch = useDispatch()
const queryClient = useQueryClient()
const { t } = useTranslation('meRoot')
const { t } = useTranslation('componentInstance')
const { theme } = useTheme()
const [instanceDomain, setInstanceDomain] = useState<string | undefined>()
const [appData, setApplicationData] = useState<InstanceLocal['appData']>()
@ -92,13 +93,14 @@ const ComponentInstance: React.FC<Props> = ({
.length
) {
Alert.alert(
'域名已存在',
'可以登录同个域名的另外一个账户,现有账户🈚️用',
t('update.local.alert.title'),
t('update.local.alert.message'),
[
{ text: '取消', style: 'cancel' },
{ text: t('update.local.alert.buttons.cancel'), style: 'cancel' },
{
text: '继续',
text: t('update.local.alert.buttons.continue'),
onPress: () => {
setApplicationData(undefined)
applicationQuery.refetch()
}
}
@ -116,8 +118,8 @@ const ComponentInstance: React.FC<Props> = ({
]
dispatch(remoteUpdate(instanceDomain))
queryClient.resetQueries(queryKey)
toast({ type: 'success', message: '重置成功' })
navigation.navigate('Screen-Public', { screen: 'Screen-Public-Root' })
toast({ type: 'success', message: t('update.remote.succeed') })
navigation.goBack()
break
}
}
@ -143,9 +145,9 @@ const ComponentInstance: React.FC<Props> = ({
const buttonContent = useMemo(() => {
switch (type) {
case 'local':
return t('content.login.button')
return t('server.button.local')
case 'remote':
return '登记'
return t('server.button.remote')
}
}, [])
@ -176,7 +178,7 @@ const ComponentInstance: React.FC<Props> = ({
keyboardType='url'
textContentType='URL'
onSubmitEditing={onSubmitEditing}
placeholder={t('content.login.server.placeholder')}
placeholder={t('server.textInput.placeholder')}
placeholderTextColor={theme.secondary}
returnKeyType='go'
/>
@ -191,21 +193,21 @@ const ComponentInstance: React.FC<Props> = ({
<View>
<InstanceInfo
visible={instanceQuery.data?.title !== undefined}
header='实例名称'
header={t('server.information.name')}
content={instanceQuery.data?.title || undefined}
potentialWidth={10}
/>
<InstanceInfo
visible={instanceQuery.data?.short_description !== undefined}
header='实例介绍'
header={t('server.information.description.heading')}
content={instanceQuery.data?.short_description || undefined}
potentialLines={5}
/>
<View style={styles.instanceStats}>
<InstanceInfo
style={{ alignItems: 'flex-start' }}
visible={instanceQuery.data?.stats?.user_count !== null}
header='用户总数'
visible={instanceQuery.data?.stats?.user_count === null}
header={t('server.information.accounts')}
content={
instanceQuery.data?.stats?.user_count?.toString() || undefined
}
@ -213,8 +215,8 @@ const ComponentInstance: React.FC<Props> = ({
/>
<InstanceInfo
style={{ alignItems: 'center' }}
visible={instanceQuery.data?.stats?.status_count !== null}
header='嘟嘟总数'
visible={instanceQuery.data?.stats?.status_count === null}
header={t('server.information.statuses')}
content={
instanceQuery.data?.stats?.status_count?.toString() || undefined
}
@ -222,22 +224,31 @@ const ComponentInstance: React.FC<Props> = ({
/>
<InstanceInfo
style={{ alignItems: 'flex-end' }}
visible={instanceQuery.data?.stats?.domain_count !== null}
header='嘟嘟总数'
visible={instanceQuery.data?.stats?.domain_count === null}
header={t('server.information.domains')}
content={
instanceQuery.data?.stats?.domain_count?.toString() || undefined
}
potentialWidth={4}
/>
</View>
<Text style={[styles.disclaimer, { color: theme.secondary }]}>
<View style={styles.disclaimer}>
<Icon
name='Lock'
size={StyleConstants.Font.Size.M}
size={StyleConstants.Font.Size.S}
color={theme.secondary}
/>{' '}
</Text>
style={styles.disclaimerIcon}
/>
<Text
style={[styles.disclaimerText, { color: theme.secondary }]}
onPress={() => Linking.openURL('https://tooot.app/privacy')}
>
{t('server.disclaimer')}
<Text style={{ color: theme.blue }}>
https://tooot.app/privacy
</Text>
</Text>
</View>
</View>
</View>
@ -275,9 +286,18 @@ const styles = StyleSheet.create({
flexDirection: 'row'
},
disclaimer: {
...StyleConstants.FontStyle.S,
flexDirection: 'row',
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
marginVertical: StyleConstants.Spacing.M
},
disclaimerIcon: {
marginTop:
(StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
marginRight: StyleConstants.Spacing.XS
},
disclaimerText: {
flex: 1,
...StyleConstants.FontStyle.S
}
})

View File

@ -3,6 +3,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import { LinearGradient } from 'expo-linear-gradient'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Dimensions, StyleSheet, Text, View, ViewStyle } from 'react-native'
import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
@ -24,6 +25,7 @@ const InstanceInfo = React.memo(
potentialWidth,
potentialLines = 1
}: Props) => {
const { t } = useTranslation('componentInstance')
const { theme } = useTheme()
const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient)
@ -40,14 +42,18 @@ const InstanceInfo = React.memo(
StyleConstants.Spacing.Global.PagePadding * 4
}
height={StyleConstants.Font.LineHeight.M * potentialLines}
shimmerColors={[theme.shimmerDefault, theme.shimmerHighlight, theme.shimmerDefault]}
shimmerColors={[
theme.shimmerDefault,
theme.shimmerHighlight,
theme.shimmerDefault
]}
>
{content ? (
<ParseHTML
content={content}
size={'M'}
numberOfLines={5}
expandHint='介绍'
expandHint={t('server.information.description.expandHint')}
/>
) : null}
</ShimmerPlaceholder>

View File

@ -19,7 +19,7 @@ export interface Props {
switchDisabled?: boolean
switchOnValueChange?: () => void
iconBack?: 'ChevronRight' | 'Check'
iconBack?: 'ChevronRight' | 'ExternalLink'
iconBackColor?: ColorDefinitions
loading?: boolean

View File

@ -1,8 +1,8 @@
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react'
import { StyleSheet, Text } from 'react-native'
import { Image } from 'react-native-expo-image-cache'
import { useTheme } from '@utils/styles/ThemeManager'
import { StyleConstants } from '@utils/styles/constants'
const regexEmoji = new RegExp(/(:[A-Za-z0-9_]+:)/)

View File

@ -7,6 +7,7 @@ import layoutAnimation from '@utils/styles/layoutAnimation'
import { useTheme } from '@utils/styles/ThemeManager'
import { LinearGradient } from 'expo-linear-gradient'
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Pressable, Text, View } from 'react-native'
import HTMLView from 'react-native-htmlview'
@ -191,6 +192,7 @@ const ParseHTML: React.FC<Props> = ({
}, [])
const rootComponent = useCallback(
({ children }) => {
const { t } = useTranslation('componentParse')
const lineHeight = StyleConstants.Font.LineHeight[size]
const [expandAllow, setExpandAllow] = useState(false)
@ -249,7 +251,9 @@ const ParseHTML: React.FC<Props> = ({
color: theme.primary
}}
>
{`${expanded ? '折叠' : '展开'}${expandHint}`}
{expanded
? t('HTML.expanded.true', { hint: expandHint })
: t('HTML.expanded.false', { hint: expandHint })}
</Text>
</LinearGradient>
</Pressable>

View File

@ -16,7 +16,7 @@ export interface Props {
const RelationshipOutgoing = React.memo(
({ id }: Props) => {
const { t } = useTranslation()
const { t } = useTranslation('componentRelationship')
const query = useRelationshipQuery({ id })
@ -30,12 +30,12 @@ const RelationshipOutgoing = React.memo(
[res]
)
},
onError: (err: any, { type }) => {
onError: (err: any, { payload: { action } }) => {
haptics('Error')
toast({
type: 'error',
message: t('common:toastMessage.error.message', {
function: t(`relationship:${type}.function`)
function: t(`button.${action}.function`)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -52,15 +52,15 @@ const RelationshipOutgoing = React.memo(
let onPress: () => void
if (query.isError) {
content = t('relationship:button.error')
content = t('button.error')
onPress = () => {}
} else {
if (query.data?.blocked_by) {
content = t('relationship:button.blocked_by')
content = t('button.blocked_by')
onPress = () => null
} else {
if (query.data?.blocking) {
content = t('relationship:button.blocking')
content = t('button.blocking')
onPress = () =>
mutation.mutate({
id,
@ -72,7 +72,7 @@ const RelationshipOutgoing = React.memo(
})
} else {
if (query.data?.following) {
content = t('relationship:button.following')
content = t('button.following')
onPress = () =>
mutation.mutate({
id,
@ -84,7 +84,7 @@ const RelationshipOutgoing = React.memo(
})
} else {
if (query.data?.requested) {
content = t('relationship:button.requested')
content = t('button.requested')
onPress = () =>
mutation.mutate({
id,
@ -95,7 +95,7 @@ const RelationshipOutgoing = React.memo(
}
})
} else {
content = t('relationship:button.default')
content = t('button.default')
onPress = () =>
mutation.mutate({
id,

View File

@ -10,7 +10,7 @@ export interface Props {
}
const RelativeTime: React.FC<Props> = ({ date }) => {
const { t } = useTranslation('relativeTime')
const { t } = useTranslation('componentRelativeTime')
return (
<TimeAgo

View File

@ -15,7 +15,7 @@ export interface Props {
const TimelineEmpty: React.FC<Props> = ({ status, refetch }) => {
const { mode, theme } = useTheme()
const { t, i18n } = useTranslation('timeline')
const { t, i18n } = useTranslation('componentTimeline')
const children = useMemo(() => {
switch (status) {

View File

@ -20,7 +20,7 @@ const TimelineEnd: React.FC<Props> = ({ hasNextPage }) => {
) : (
<Text style={[styles.text, { color: theme.secondary }]}>
<Trans
i18nKey='timeline:shared.end.message'
i18nKey='componentTimeline:end.message'
components={[
<Icon
name='Coffee'

View File

@ -4,11 +4,13 @@ import { StyleConstants } from '@root/utils/styles/constants'
import { useTheme } from '@root/utils/styles/ThemeManager'
import { updatePublicRemoteNotice } from '@utils/slices/contextsSlice'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyleSheet, Text, View } from 'react-native'
import { useDispatch } from 'react-redux'
const TimelineHeader = React.memo(
() => {
const { t } = useTranslation('componentTimeline')
const dispatch = useDispatch()
const navigation = useNavigation()
const { theme } = useTheme()
@ -16,7 +18,7 @@ const TimelineHeader = React.memo(
return (
<View style={[styles.base, { borderColor: theme.border }]}>
<Text style={[styles.text, { color: theme.primary }]}>
{' '}
{t('header.explanation')}
<Text
style={{ color: theme.blue }}
onPress={() => {
@ -27,7 +29,7 @@ const TimelineHeader = React.memo(
})
}}
>
{' '}
{t('header.button')}
<Icon
name='ArrowRight'
size={StyleConstants.Font.Size.S}

View File

@ -18,7 +18,7 @@ const TimelineActioned: React.FC<Props> = ({
action,
notification = false
}) => {
const { t } = useTranslation('timeline')
const { t } = useTranslation('componentTimeline')
const { theme } = useTheme()
const navigation = useNavigation()
const name = account.display_name || account.username

View File

@ -11,14 +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 {
Platform,
Pressable,
Share,
StyleSheet,
Text,
View
} from 'react-native'
import { Pressable, StyleSheet, Text, View } from 'react-native'
import { useQueryClient } from 'react-query'
export interface Props {
@ -29,7 +22,7 @@ export interface Props {
const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
const navigation = useNavigation()
const { t } = useTranslation()
const { t } = useTranslation('componentTimeline')
const { theme } = useTheme()
const iconColor = theme.secondary
const iconColorAction = (state: boolean) =>
@ -84,7 +77,7 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
type: 'error',
message: t('common:toastMessage.error.message', {
function: t(
`timeline:shared.actions.${correctParam.payload.property}.function`
`shared.actions.${correctParam.payload.property}.function`
)
}),
...(err.status &&
@ -95,7 +88,7 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
description: err.data.error
})
})
queryClient.setQueryData(queryKey, oldData)
queryClient.invalidateQueries(queryKey)
}
})
@ -150,18 +143,6 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
}),
[status.bookmarked]
)
const onPressShare = useCallback(() => {
switch (Platform.OS) {
case 'ios':
return Share.share({
url: status.uri
})
case 'android':
return Share.share({
message: status.uri
})
}
}, [])
const childrenReply = useMemo(
() => (
@ -220,12 +201,6 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
),
[status.bookmarked]
)
const childrenShare = useMemo(
() => (
<Icon name='Share2' color={iconColor} size={StyleConstants.Font.Size.L} />
),
[]
)
return (
<>
@ -256,12 +231,6 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
onPress={onPressBookmark}
children={childrenBookmark}
/>
<Pressable
style={styles.action}
onPress={onPressShare}
children={childrenShare}
/>
</View>
</>
)
@ -269,16 +238,13 @@ const TimelineActions: React.FC<Props> = ({ queryKey, status, reblog }) => {
const styles = StyleSheet.create({
actions: {
width: '100%',
flex: 1,
flexDirection: 'row',
marginTop: StyleConstants.Spacing.S
},
action: {
width: '20%',
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingVertical: StyleConstants.Spacing.S
}
})

View File

@ -17,7 +17,7 @@ export interface Props {
}
const TimelineAttachment: React.FC<Props> = ({ status }) => {
const { t } = useTranslation('timeline')
const { t } = useTranslation('componentTimeline')
const [sensitiveShown, setSensitiveShown] = useState(status.sensitive)
const onPressBlurView = useCallback(() => {

View File

@ -22,7 +22,7 @@ const AttachmentUnsupported: React.FC<Props> = ({
sensitiveShown,
attachment
}) => {
const { t } = useTranslation('timeline')
const { t } = useTranslation('componentTimeline')
const { theme } = useTheme()
return (

View File

@ -17,7 +17,7 @@ const TimelineContent: React.FC<Props> = ({
highlighted = false,
disableDetails = false
}) => {
const { t } = useTranslation('timeline')
const { t } = useTranslation('componentTimeline')
return (
<>

View File

@ -20,30 +20,29 @@ const HeaderActionsAccount: React.FC<Props> = ({
account,
setBottomSheetVisible
}) => {
const { t } = useTranslation()
const { t } = useTranslation('componentTimeline')
const queryClient = useQueryClient()
const mutateion = useTimelineMutation({
queryClient,
onSuccess: (_, { type }) => {
onSuccess: (_, { payload: { property } }) => {
haptics('Success')
toast({
type: 'success',
message: t('common:toastMessage.success.message', {
function: t(
`timeline:shared.header.default.actions.account.${type}.function`,
{ acct: account.acct }
)
function: t(`shared.header.actions.account.${property}.function`, {
acct: account.acct
})
})
})
},
onError: (err: any, { type }) => {
onError: (err: any, { payload: { property } }) => {
haptics('Error')
toast({
type: 'error',
message: t('common:toastMessage.error.message', {
function: t(
`timeline:shared.header.default.actions.account.${type}.function`,
`shared.header.actions.account.${property}.function`,
{ acct: account.acct }
)
}),
@ -64,7 +63,7 @@ const HeaderActionsAccount: React.FC<Props> = ({
return (
<MenuContainer>
<MenuHeader
heading={t('timeline:shared.header.default.actions.account.heading')}
heading={t('shared.header.actions.account.heading')}
/>
<MenuRow
onPress={() => {
@ -77,7 +76,7 @@ const HeaderActionsAccount: React.FC<Props> = ({
})
}}
iconFront='EyeOff'
title={t('timeline:shared.header.default.actions.account.mute.button', {
title={t('shared.header.actions.account.mute.button', {
acct: account.acct
})}
/>
@ -93,7 +92,7 @@ const HeaderActionsAccount: React.FC<Props> = ({
}}
iconFront='XCircle'
title={t(
'timeline:shared.header.default.actions.account.block.button',
'shared.header.actions.account.block.button',
{
acct: account.acct
}
@ -111,7 +110,7 @@ const HeaderActionsAccount: React.FC<Props> = ({
}}
iconFront='Flag'
title={t(
'timeline:shared.header.default.actions.account.report.button',
'shared.header.actions.account.reports.button',
{
acct: account.acct
}

View File

@ -22,7 +22,7 @@ const HeaderActionsDomain: React.FC<Props> = ({
domain,
setBottomSheetVisible
}) => {
const { t } = useTranslation()
const { t } = useTranslation('componentTimeline')
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
queryClient,
@ -30,9 +30,7 @@ const HeaderActionsDomain: React.FC<Props> = ({
toast({
type: 'success',
message: t('common:toastMessage.success.message', {
function: t(
`timeline:shared.header.default.actions.domain.block.function`
)
function: t(`shared.header.actions.domain.block.function`)
})
})
queryClient.invalidateQueries(queryKey)
@ -41,20 +39,19 @@ const HeaderActionsDomain: React.FC<Props> = ({
return (
<MenuContainer>
<MenuHeader
heading={t(`timeline:shared.header.default.actions.domain.heading`)}
/>
<MenuHeader heading={t(`shared.header.actions.domain.heading`)} />
<MenuRow
onPress={() => {
Alert.alert(
t('timeline:shared.header.default.actions.domain.alert.title'),
t('timeline:shared.header.default.actions.domain.alert.message'),
t('shared.header.actions.domain.alert.title', { domain }),
t('shared.header.actions.domain.alert.message'),
[
{ text: t('common:buttons.cancel'), style: 'cancel' },
{
text: t(
'timeline:shared.header.default.actions.domain.alert.confirm'
),
text: t('shared.header.actions.domain.alert.buttons.cancel'),
style: 'cancel'
},
{
text: t('shared.header.actions.domain.alert.buttons.confirm'),
style: 'destructive',
onPress: () => {
setBottomSheetVisible(false)
@ -69,7 +66,7 @@ const HeaderActionsDomain: React.FC<Props> = ({
)
}}
iconFront='CloudOff'
title={t(`timeline:shared.header.default.actions.domain.block.button`, {
title={t(`shared.header.actions.domain.block.button`, {
domain
})}
/>

View File

@ -7,17 +7,20 @@ import { useTheme } from '@utils/styles/ThemeManager'
import React, { useCallback, useMemo, useState } from 'react'
import { Pressable, StyleSheet } from 'react-native'
import { useSelector } from 'react-redux'
import HeaderActionsAccount from './ActionsAccount'
import HeaderActionsDomain from './ActionsDomain'
import HeaderActionsStatus from './ActionsStatus'
import HeaderActionsAccount from './Account'
import HeaderActionsDomain from './Domain'
import HeaderActionsShare from './Share'
import HeaderActionsStatus from './Status'
export interface Props {
queryKey: QueryKeyTimeline
status: Mastodon.Status
url?: string
type?: 'status' | 'account'
}
const HeaderActions = React.memo(
({ queryKey, status }: Props) => {
({ queryKey, status, url, type }: Props) => {
const { theme } = useTheme()
const localAccount = useSelector(getLocalAccount)
@ -73,6 +76,14 @@ const HeaderActions = React.memo(
setBottomSheetVisible={setBottomSheetVisible}
/>
)}
{url && type ? (
<HeaderActionsShare
url={url}
type={type}
setBottomSheetVisible={setBottomSheetVisible}
/>
) : null}
</BottomSheet>
)}
</>

View File

@ -0,0 +1,52 @@
import MenuContainer from '@components/Menu/Container'
import MenuHeader from '@components/Menu/Header'
import MenuRow from '@components/Menu/Row'
import { toast } from '@components/toast'
import {
QueryKeyTimeline,
useTimelineMutation
} from '@utils/queryHooks/timeline'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Platform, Share } from 'react-native'
export interface Props {
type: 'status' | 'account'
url: string
setBottomSheetVisible: React.Dispatch<React.SetStateAction<boolean>>
}
const HeaderActionsShare: React.FC<Props> = ({
type,
url,
setBottomSheetVisible
}) => {
const { t } = useTranslation('componentTimeline')
return (
<MenuContainer>
<MenuHeader heading={t(`shared.header.actions.share.${type}.heading`)} />
<MenuRow
iconFront='Share2'
title={t(`shared.header.actions.share.${type}.button`)}
onPress={async () => {
switch (Platform.OS) {
case 'ios':
await Share.share({
url
})
break
case 'android':
await Share.share({
message: url
})
break
}
setBottomSheetVisible(false)
}}
/>
</MenuContainer>
)
}
export default HeaderActionsShare

View File

@ -23,7 +23,7 @@ const HeaderActionsStatus: React.FC<Props> = ({
setBottomSheetVisible
}) => {
const navigation = useNavigation()
const { t } = useTranslation()
const { t } = useTranslation('componentTimeline')
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
@ -38,7 +38,7 @@ const HeaderActionsStatus: React.FC<Props> = ({
type: 'error',
message: t('common:toastMessage.error.message', {
function: t(
`timeline:shared.header.default.actions.status.${theFunction}.function`
`shared.header.actions.status.${theFunction}.function`
)
}),
...(err.status &&
@ -56,7 +56,7 @@ const HeaderActionsStatus: React.FC<Props> = ({
return (
<MenuContainer>
<MenuHeader
heading={t('timeline:shared.header.default.actions.status.heading')}
heading={t('shared.header.actions.status.heading')}
/>
<MenuRow
onPress={() => {
@ -69,20 +69,20 @@ const HeaderActionsStatus: React.FC<Props> = ({
})
}}
iconFront='Trash'
title={t('timeline:shared.header.default.actions.status.delete.button')}
title={t('shared.header.actions.status.delete.button')}
/>
<MenuRow
onPress={() => {
Alert.alert(
t('timeline:shared.header.default.actions.status.edit.alert.title'),
t('shared.header.actions.status.edit.alert.title'),
t(
'timeline:shared.header.default.actions.status.edit.alert.message'
'shared.header.actions.status.edit.alert.message'
),
[
{ text: t('common:buttons.cancel'), style: 'cancel' },
{ text: t('shared.header.actions.status.edit.alert.buttons.cancel'), style: 'cancel' },
{
text: t(
'timeline:shared.header.default.actions.status.edit.alert.confirm'
'shared.header.actions.status.edit.alert.buttons.confirm'
),
style: 'destructive',
onPress: async () => {
@ -105,8 +105,8 @@ const HeaderActionsStatus: React.FC<Props> = ({
]
)
}}
iconFront='Trash'
title={t('timeline:shared.header.default.actions.status.edit.button')}
iconFront='Edit'
title={t('shared.header.actions.status.edit.button')}
/>
<MenuRow
onPress={() => {
@ -122,10 +122,10 @@ const HeaderActionsStatus: React.FC<Props> = ({
title={
status.muted
? t(
'timeline:shared.header.default.actions.status.mute.button.negative'
'shared.header.actions.status.mute.button.negative'
)
: t(
'timeline:shared.header.default.actions.status.mute.button.positive'
'shared.header.actions.status.mute.button.positive'
)
}
/>
@ -145,10 +145,10 @@ const HeaderActionsStatus: React.FC<Props> = ({
title={
status.pinned
? t(
'timeline:shared.header.default.actions.status.pin.button.negative'
'shared.header.actions.status.pin.button.negative'
)
: t(
'timeline:shared.header.default.actions.status.pin.button.positive'
'shared.header.actions.status.pin.button.positive'
)
}
/>

View File

@ -21,7 +21,7 @@ export interface Props {
}
const HeaderConversation: React.FC<Props> = ({ queryKey, conversation }) => {
const { t } = useTranslation()
const { t } = useTranslation('componentTimeline')
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
@ -32,7 +32,7 @@ const HeaderConversation: React.FC<Props> = ({ queryKey, conversation }) => {
toast({
type: 'error',
message: t('common:toastMessage.error.message', {
function: t(`timeline:shared.header.conversation.delete.function`)
function: t(`shared.header.conversation.delete.function`)
}),
...(err.status &&
typeof err.status === 'number' &&

View File

@ -27,7 +27,14 @@ const TimelineHeaderDefault: React.FC<Props> = ({ queryKey, status }) => {
</View>
</View>
{queryKey ? <HeaderActions queryKey={queryKey} status={status} /> : null}
{queryKey ? (
<HeaderActions
queryKey={queryKey}
status={status}
url={status.url || status.uri}
type='status'
/>
) : null}
</View>
)
}

View File

@ -11,7 +11,7 @@ export interface Props {
const HeaderSharedApplication: React.FC<Props> = ({ application }) => {
const { theme } = useTheme()
const { t } = useTranslation('timeline')
const { t } = useTranslation('componentTimeline')
return application && application.name !== 'Web' ? (
<Text

View File

@ -2,7 +2,6 @@ import RelativeTime from '@components/RelativeTime'
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 {
@ -11,7 +10,6 @@ export interface Props {
const HeaderSharedCreated: React.FC<Props> = ({ created_at }) => {
const { theme } = useTheme()
const { i18n } = useTranslation()
return (
<Text style={[styles.created_at, { color: theme.secondary }]}>

View File

@ -5,6 +5,7 @@ import { ParseEmojis } from '@components/Parse'
import RelativeTime from '@components/RelativeTime'
import { toast } from '@components/toast'
import {
MutationVarsTimelineUpdateStatusProperty,
QueryKeyTimeline,
useTimelineMutation
} from '@utils/queryHooks/timeline'
@ -32,7 +33,7 @@ const TimelinePoll: React.FC<Props> = ({
sameAccount
}) => {
const { mode, theme } = useTheme()
const { t } = useTranslation('timeline')
const { t } = useTranslation('componentTimeline')
const [allOptions, setAllOptions] = useState(
new Array(poll.options.length).fill(false)
@ -42,19 +43,21 @@ const TimelinePoll: React.FC<Props> = ({
const mutation = useTimelineMutation({
queryClient,
onSuccess: true,
onError: (err: any) => {
onError: (err: any, params) => {
const theParams = params as MutationVarsTimelineUpdateStatusProperty
haptics('Error')
toast({
type: 'error',
message: '投票错误',
message: t('common:toastMessage.error.message', {
function: t(`shared.poll.meta.button.${theParams.payload.type}`)
}),
...(err.status &&
typeof err.status === 'number' &&
err.data &&
err.data.error &&
typeof err.data.error === 'string' && {
description: err.data.error
}),
autoHide: false
})
})
queryClient.invalidateQueries(queryKey)
}

View File

@ -1,5 +1,4 @@
import * as Analytics from 'expo-firebase-analytics'
import * as Sentry from 'sentry-expo'
const analytics = (event: string, params?: { [key: string]: string }) => {
Analytics.logEvent(event, params).catch(