Update i18next type

This commit is contained in:
xmflsct 2022-12-23 15:53:40 +01:00
parent b388853429
commit e32125ad17
49 changed files with 1054 additions and 896 deletions

View File

@ -16,7 +16,7 @@ PODS:
- ExpoModulesCore
- EXNotifications (0.17.0):
- ExpoModulesCore
- Expo (47.0.8):
- Expo (47.0.9):
- ExpoModulesCore
- ExpoCrypto (12.0.0):
- ExpoModulesCore
@ -26,7 +26,7 @@ PODS:
- ExpoModulesCore
- ExpoLocalization (14.0.0):
- ExpoModulesCore
- ExpoModulesCore (1.0.3):
- ExpoModulesCore (1.0.4):
- React-Core
- ReactCommon/turbomodule/core
- ExpoRandom (13.0.0):
@ -297,7 +297,7 @@ PODS:
- React-Core
- react-native-cameraroll (5.2.0):
- React-Core
- react-native-image-picker (4.10.2):
- react-native-image-picker (4.10.3):
- React-Core
- react-native-ios-context-menu (1.15.1):
- React-Core
@ -694,12 +694,12 @@ SPEC CHECKSUMS:
EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
Expo: 36b5f625d36728adbdd1934d4d57182f319ab832
Expo: 5523a4835730104a301caeac1e68dad095a9dfff
ExpoCrypto: 51e7662c7f5bfeab25b7909b8a5d545ec15d4877
ExpoHaptics: 5a56d30a87ea213dd00b09566dc4b441a4dff97f
ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318
ExpoLocalization: e202d1e2a4950df17ac8d0889d65a1ffd7532d7e
ExpoModulesCore: b5d21c8880afda6fb6ee95469f9ac2ec9b98e995
ExpoModulesCore: 8211c89bcc3ba86e2d02c54b1d31f1fa81acb6de
ExpoRandom: 58b7e0a5fe1adf1cb6dc1cbe503a6fe9524f36ce
ExpoStoreReview: ff6d631f2949eb7e4b2d14146ef6af25a16d770d
ExpoWebBrowser: 073e50f16669d498fb49063b9b7fe780b24f7fda
@ -732,7 +732,7 @@ SPEC CHECKSUMS:
react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3
react-native-blurhash: add4df9a937b4e021a24bc67a0714f13e0bd40b7
react-native-cameraroll: 0ff04cc4e0ff5f19a94ff4313e5c8bc4503cd86d
react-native-image-picker: bf34f3f516d139ed3e24c5f5a381a91819e349ea
react-native-image-picker: 60f4246eb5bb7187fc15638a8c1f13abd3820695
react-native-ios-context-menu: b170594b4448c0cd10c79e13432216bac99de1ac
react-native-language-detection: f414937fa715108ab50a6269a3de0bcb95e4ceb0
react-native-menu: 8e172cfcf0e42e92f028e7781eddf84d430cae24

View File

@ -1,8 +1,46 @@
import 'i18next'
import common from '../i18n/en/common.json'
import screens from '../i18n/en/screens.json'
import screenAccountSelection from '../i18n/en/screens/accountSelection.json'
import screenActions from '../i18n/en/screens/actions.json'
import screenAnnouncements from '../i18n/en/screens/announcements.json'
import screenCompose from '../i18n/en/screens/compose.json'
import screenImageViewer from '../i18n/en/screens/imageViewer.json'
import screenTabs from '../i18n/en/screens/tabs.json'
import componentContextMenu from '../i18n/en/components/contextMenu.json'
import componentEmojis from '../i18n/en/components/emojis.json'
import componentInstance from '../i18n/en/components/instance.json'
import componentMediaSelector from '../i18n/en/components/mediaSelector.json'
import componentParse from '../i18n/en/components/parse.json'
import componentRelationship from '../i18n/en/components/relationship.json'
import componentTimeline from '../i18n/en/components/timeline.json'
declare module 'i18next' {
interface CustomTypeOptions {
defaultNS: 'common',
defaultNS: 'common'
resources: {
common: typeof common
screens: typeof screens
screenAccountSelection: typeof screenAccountSelection
screenActions: typeof screenActions
screenAnnouncements: typeof screenAnnouncements
screenCompose: typeof screenCompose
screenImageViewer: typeof screenImageViewer
screenTabs: typeof screenTabs
componentContextMenu: typeof componentContextMenu
componentEmojis: typeof componentEmojis
componentInstance: typeof componentInstance
componentMediaSelector: typeof componentMediaSelector
componentParse: typeof componentParse
componentRelationship: typeof componentRelationship
componentTimeline: typeof componentTimeline
}
returnNull: false
returnEmptyString: false
}
}

View File

@ -39,7 +39,12 @@ export interface Props {
}
const Screens: React.FC<Props> = ({ localCorrupt }) => {
const { t } = useTranslation('screens')
const { t } = useTranslation([
'common',
'screens',
'screenAnnouncements',
'screenAccountSelection'
])
const dispatch = useAppDispatch()
const instanceActive = useSelector(getInstanceActive)
const { colors, theme } = useTheme()
@ -55,7 +60,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
// Prevent screenshot alert
useEffect(() => {
const screenshotListener = addScreenshotListener(() =>
Alert.alert(t('screenshot.title'), t('screenshot.message'), [
Alert.alert(t('screens:screenshot.title'), t('screens:screenshot.message'), [
{ text: t('common:buttons.confirm'), style: 'destructive' }
])
)
@ -68,7 +73,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
const showLocalCorrect = () => {
if (localCorrupt) {
displayMessage({
message: t('localCorrupt.message'),
message: t('screens:localCorrupt.message'),
description: localCorrupt.length ? localCorrupt : undefined,
type: 'danger'
})
@ -176,7 +181,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
if (!typesImage.includes(mime.split('/')[1])) {
console.warn('Image type not supported:', mime.split('/')[1])
displayMessage({
message: t('shareError.imageNotSupported', {
message: t('screens:shareError.imageNotSupported', {
type: mime.split('/')[1]
}),
type: 'danger'
@ -188,7 +193,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
if (!typesVideo.includes(mime.split('/')[1])) {
console.warn('Video type not supported:', mime.split('/')[1])
displayMessage({
message: t('shareError.videoNotSupported', {
message: t('screens:shareError.videoNotSupported', {
type: mime.split('/')[1]
}),
type: 'danger'

View File

@ -7,7 +7,6 @@ import { chunk, forEach, groupBy, sortBy } from 'lodash'
import React, { createRef, PropsWithChildren, useEffect, useReducer, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Keyboard, KeyboardAvoidingView, View } from 'react-native'
import FastImage from 'react-native-fast-image'
import { Edge, SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
import { useSelector } from 'react-redux'
import EmojisContext, { Emojis, emojisReducer, EmojisState } from './Emojis/helpers/EmojisContext'
@ -35,7 +34,7 @@ const ComponentEmojis: React.FC<Props & PropsWithChildren> = ({
emojisDispatch({ type: 'input', payload: inputProps })
}, [inputProps])
const { t } = useTranslation()
const { t } = useTranslation(['componentEmojis'])
const { data } = useEmojisQuery({})
const frequentEmojis = useSelector(getInstanceFrequentEmojis, () => true)
useEffect(() => {

View File

@ -25,7 +25,7 @@ import EmojisContext from './helpers/EmojisContext'
const EmojisList = () => {
const dispatch = useAppDispatch()
const { reduceMotionEnabled } = useAccessibility()
const { t } = useTranslation()
const { t } = useTranslation(['common', 'screenCompose'])
const { emojisState, emojisDispatch } = useContext(EmojisContext)
const { colors } = useTheme()

View File

@ -35,7 +35,7 @@ const ComponentInstance: React.FC<Props> = ({
disableHeaderImage,
goBack = false
}) => {
const { t } = useTranslation('componentInstance')
const { t } = useTranslation(['common', 'componentInstance'])
const { colors, mode } = useTheme()
const navigation = useNavigation<TabMeStackNavigationProp<'Tab-Me-Root' | 'Tab-Me-Switch'>>()
@ -113,16 +113,20 @@ const ComponentInstance: React.FC<Props> = ({
const processUpdate = useCallback(() => {
if (domain) {
if (instances && instances.filter(instance => instance.url === domain).length) {
Alert.alert(t('update.alert.title'), t('update.alert.message'), [
{
text: t('common:buttons.cancel'),
style: 'cancel'
},
{
text: t('common:buttons.continue'),
onPress: () => appsMutation.mutate({ domain })
}
])
Alert.alert(
t('componentInstance:update.alert.title'),
t('componentInstance:update.alert.message'),
[
{
text: t('common:buttons.cancel'),
style: 'cancel'
},
{
text: t('common:buttons.continue'),
onPress: () => appsMutation.mutate({ domain })
}
]
)
} else {
appsMutation.mutate({ domain })
}
@ -209,7 +213,7 @@ const ComponentInstance: React.FC<Props> = ({
processUpdate()
}
}}
placeholder={' ' + t('server.textInput.placeholder')}
placeholder={' ' + t('componentInstance:server.textInput.placeholder')}
placeholderTextColor={colors.secondary}
returnKeyType='go'
keyboardAppearance={mode}
@ -222,7 +226,7 @@ const ComponentInstance: React.FC<Props> = ({
/>
<Button
type='text'
content={t('server.button')}
content={t('componentInstance:server.button')}
onPress={processUpdate}
disabled={!instanceQuery.data?.uri && !whitelisted}
loading={instanceQuery.isFetching || appsMutation.isLoading}
@ -239,31 +243,31 @@ const ComponentInstance: React.FC<Props> = ({
paddingTop: StyleConstants.Spacing.XS
}}
>
{t('server.whitelisted')}
{t('componentInstance:server.whitelisted')}
</CustomText>
) : (
<Placeholder>
<InstanceInfo
header={t('server.information.name')}
header={t('componentInstance:server.information.name')}
content={instanceQuery.data?.title || undefined}
potentialWidth={2}
/>
<View style={{ flex: 1, flexDirection: 'row' }}>
<InstanceInfo
style={{ alignItems: 'flex-start' }}
header={t('server.information.accounts')}
header={t('componentInstance:server.information.accounts')}
content={instanceQuery.data?.stats?.user_count?.toString() || undefined}
potentialWidth={4}
/>
<InstanceInfo
style={{ alignItems: 'center' }}
header={t('server.information.statuses')}
header={t('componentInstance:server.information.statuses')}
content={instanceQuery.data?.stats?.status_count?.toString() || undefined}
potentialWidth={4}
/>
<InstanceInfo
style={{ alignItems: 'flex-end' }}
header={t('server.information.domains')}
header={t('componentInstance:server.information.domains')}
content={instanceQuery.data?.stats?.domain_count?.toString() || undefined}
potentialWidth={4}
/>
@ -287,7 +291,7 @@ const ComponentInstance: React.FC<Props> = ({
}}
/>
<CustomText fontStyle='S' style={{ flex: 1, color: colors.secondary }}>
{t('server.disclaimer.base')}
{t('componentInstance:server.disclaimer.base')}
</CustomText>
</View>
<View
@ -312,7 +316,8 @@ const ComponentInstance: React.FC<Props> = ({
accessibilityRole='link'
>
<Trans
i18nKey='componentInstance:server.terms.base'
ns='componentInstance'
i18nKey='server.terms.base'
components={[
<CustomText
accessible

View File

@ -16,7 +16,7 @@ export interface Props {
const RelationshipIncoming: React.FC<Props> = ({ id }) => {
const { theme } = useTheme()
const { t } = useTranslation()
const { t } = useTranslation(['common', 'componentRelationship'])
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
const queryKeyNotification: QueryKeyTimeline = ['Timeline', { page: 'Notifications' }]
@ -33,7 +33,7 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
type: 'error',
theme,
message: t('common:message.error.message', {
function: t(`relationship:${type}.function`)
function: t(`componentRelationship:${type}.function`)
}),
...(err.status &&
typeof err.status === 'number' &&

View File

@ -22,7 +22,7 @@ export interface Props {
const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
const { theme } = useTheme()
const { t } = useTranslation('componentRelationship')
const { t } = useTranslation(['common', 'componentRelationship'])
const canFollowNotify = useSelector(checkInstanceFeature('account_follow_notify'))
@ -44,7 +44,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
theme,
type: 'error',
message: t('common:message.error.message', {
function: t(`${action}.function`)
function: t(`componentRelationship:${action}.function`)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -61,15 +61,15 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
let onPress: () => void
if (query.isError) {
content = t('button.error')
content = t('componentRelationship:button.error')
onPress = () => {}
} else {
if (query.data?.blocked_by) {
content = t('button.blocked_by')
content = t('componentRelationship:button.blocked_by')
onPress = () => {}
} else {
if (query.data?.blocking) {
content = t('button.blocking')
content = t('componentRelationship:button.blocking')
onPress = () => {
mutation.mutate({
id,
@ -82,7 +82,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
}
} else {
if (query.data?.following) {
content = t('button.following')
content = t('componentRelationship:button.following')
onPress = () => {
mutation.mutate({
id,
@ -95,7 +95,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
}
} else {
if (query.data?.requested) {
content = t('button.requested')
content = t('componentRelationship:button.requested')
onPress = () => {
mutation.mutate({
id,
@ -107,7 +107,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => {
})
}
} else {
content = t('button.default')
content = t('componentRelationship:button.default')
onPress = () => {
mutation.mutate({
id,

View File

@ -45,7 +45,8 @@ const TimelineFooter = React.memo(
) : (
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
<Trans
i18nKey='componentTimeline:end.message'
ns='componentTimeline'
i18nKey='end.message'
components={[
<Icon name='Coffee' size={StyleConstants.Font.Size.S} color={colors.secondary} />
]}

View File

@ -28,7 +28,7 @@ const TimelineActions: React.FC = () => {
if (!queryKey || !status || disableDetails) return null
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>()
const { t } = useTranslation('componentTimeline')
const { t } = useTranslation(['common', 'componentTimeline'])
const { colors, theme } = useTheme()
const iconColor = colors.secondary
@ -54,13 +54,13 @@ const TimelineActions: React.FC = () => {
queryClient.invalidateQueries(tempQueryKey)
}
},
onError: (err: any, params, oldData) => {
onError: (err: any, params) => {
const correctParam = params as MutationVarsTimelineUpdateStatusProperty
displayMessage({
theme,
type: 'error',
message: t('common:message.error.message', {
function: t(`shared.actions.${correctParam.payload.property}.function`)
function: t(`componentTimeline:shared.actions.${correctParam.payload.property}.function`)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -94,10 +94,10 @@ const TimelineActions: React.FC = () => {
if (!status.reblogged) {
showActionSheetWithOptions(
{
title: t('shared.actions.reblogged.options.title'),
title: t('componentTimeline:shared.actions.reblogged.options.title'),
options: [
t('shared.actions.reblogged.options.public'),
t('shared.actions.reblogged.options.unlisted'),
t('componentTimeline:shared.actions.reblogged.options.public'),
t('componentTimeline:shared.actions.reblogged.options.unlisted'),
t('common:buttons.cancel')
],
cancelButtonIndex: 2,
@ -269,7 +269,7 @@ const TimelineActions: React.FC = () => {
<Pressable
{...(highlighted
? {
accessibilityLabel: t('shared.actions.reply.accessibilityLabel'),
accessibilityLabel: t('componentTimeline:shared.actions.reply.accessibilityLabel'),
accessibilityRole: 'button'
}
: { accessibilityLabel: '' })}
@ -281,7 +281,9 @@ const TimelineActions: React.FC = () => {
<Pressable
{...(highlighted
? {
accessibilityLabel: t('shared.actions.reblogged.accessibilityLabel'),
accessibilityLabel: t(
'componentTimeline:shared.actions.reblogged.accessibilityLabel'
),
accessibilityRole: 'button'
}
: { accessibilityLabel: '' })}
@ -296,7 +298,9 @@ const TimelineActions: React.FC = () => {
<Pressable
{...(highlighted
? {
accessibilityLabel: t('shared.actions.favourited.accessibilityLabel'),
accessibilityLabel: t(
'componentTimeline:shared.actions.favourited.accessibilityLabel'
),
accessibilityRole: 'button'
}
: { accessibilityLabel: '' })}
@ -308,7 +312,9 @@ const TimelineActions: React.FC = () => {
<Pressable
{...(highlighted
? {
accessibilityLabel: t('shared.actions.bookmarked.accessibilityLabel'),
accessibilityLabel: t(
'componentTimeline:shared.actions.bookmarked.accessibilityLabel'
),
accessibilityRole: 'button'
}
: { accessibilityLabel: '' })}

View File

@ -15,7 +15,7 @@ export interface FilteredProps {
const TimelineFiltered: React.FC<FilteredProps> = ({ filterResults }) => {
const { colors } = useTheme()
const { t } = useTranslation('componentTimeline')
const { t } = useTranslation(['common', 'componentTimeline'])
const main = () => {
if (!filterResults?.length) {
@ -23,18 +23,27 @@ const TimelineFiltered: React.FC<FilteredProps> = ({ filterResults }) => {
}
switch (typeof filterResults[0]) {
case 'string': // v1 filter
return <>{t('shared.filtered.match', { context: 'v1', phrase: filterResults[0] })}</>
return (
<>
{t('componentTimeline:shared.filtered.match', {
defaultValue: 'v1',
context: 'v1',
phrase: filterResults[0]
})}
</>
)
default:
return (
<>
{t('shared.filtered.match', {
{t('componentTimeline:shared.filtered.match', {
defaultValue: 'v2',
context: 'v2',
count: filterResults.length,
filters: filterResults.map(result => result.title).join(t('common:separator'))
})}
<CustomText
style={{ color: colors.blue }}
children={`\n${t('shared.filtered.reveal')}`}
children={`\n${t('componentTimeline:shared.filtered.reveal')}`}
/>
</>
)

View File

@ -22,7 +22,7 @@ const HeaderConversation = ({ conversation }: Props) => {
if (!queryKey) return null
const { colors, theme } = useTheme()
const { t } = useTranslation('componentTimeline')
const { t } = useTranslation(['common', 'componentTimeline'])
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
@ -32,7 +32,7 @@ const HeaderConversation = ({ conversation }: Props) => {
theme,
type: 'error',
message: t('common:message.error.message', {
function: t(`shared.header.conversation.delete.function`)
function: t(`componentTimeline:shared.header.conversation.delete.function`)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -53,7 +53,7 @@ const HeaderConversation = ({ conversation }: Props) => {
numberOfLines={1}
style={{ ...StyleConstants.FontStyle.M, color: colors.secondary }}
>
<CustomText>{t('shared.header.conversation.withAccounts')}</CustomText>
<CustomText>{t('componentTimeline:shared.header.conversation.withAccounts')}</CustomText>
{conversation.accounts.map((account, index) => (
<CustomText key={account.id} numberOfLines={1}>
{index !== 0 ? t('common:separator') : undefined}

View File

@ -33,7 +33,7 @@ const TimelinePoll: React.FC = () => {
const poll = status.poll
const { colors, theme } = useTheme()
const { t } = useTranslation('componentTimeline')
const { t } = useTranslation(['common', 'componentTimeline'])
const [allOptions, setAllOptions] = useState(new Array(status.poll.options.length).fill(false))
@ -58,8 +58,7 @@ const TimelinePoll: React.FC = () => {
theme,
type: 'error',
message: t('common:message.error.message', {
// @ts-ignore
function: t(`shared.poll.meta.button.${theParams.payload.type}`)
function: t(`componentTimeline:shared.poll.meta.button.${theParams.payload.type}` as any)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -95,7 +94,7 @@ const TimelinePoll: React.FC = () => {
})
}
type='text'
content={t('shared.poll.meta.button.vote')}
content={t('componentTimeline:shared.poll.meta.button.vote')}
loading={mutation.isLoading}
disabled={allOptions.filter(o => o !== false).length === 0}
/>
@ -120,7 +119,7 @@ const TimelinePoll: React.FC = () => {
})
}
type='text'
content={t('shared.poll.meta.button.refresh')}
content={t('componentTimeline:shared.poll.meta.button.refresh')}
loading={mutation.isLoading}
/>
</View>
@ -233,20 +232,25 @@ const TimelinePoll: React.FC = () => {
const pollVoteCounts = () => {
if (poll.voters_count !== null) {
return t('shared.poll.meta.count.voters', { count: poll.voters_count }) + ' • '
return (
t('componentTimeline:shared.poll.meta.count.voters', { count: poll.voters_count }) + ' • '
)
} else if (poll.votes_count !== null) {
return t('shared.poll.meta.count.votes', { count: poll.votes_count }) + ' • '
return (
t('componentTimeline:shared.poll.meta.count.votes', { count: poll.votes_count }) + ' • '
)
}
}
const pollExpiration = () => {
if (poll.expired) {
return t('shared.poll.meta.expiration.expired')
return t('componentTimeline:shared.poll.meta.expiration.expired')
} else {
if (poll.expires_at) {
return (
<Trans
i18nKey='componentTimeline:shared.poll.meta.expiration.until'
ns='componentTimeline'
i18nKey='shared.poll.meta.expiration.until'
components={[<RelativeTime time={poll.expires_at} />]}
/>
)

View File

@ -16,7 +16,7 @@ const TimelineTranslate = () => {
const { status, highlighted, rawContent, detectedLanguage } = useContext(StatusContext)
if (!status || !highlighted || !rawContent?.current.length) return null
const { t } = useTranslation('componentTimeline')
const { t } = useTranslation(['componentTimeline'])
const { colors } = useTheme()
const [detected, setDetected] = useState<{
@ -101,15 +101,15 @@ const TimelineTranslate = () => {
}}
>
{isError
? t('shared.translate.failed')
? t('componentTimeline:shared.translate.failed')
: isSuccess
? typeof data?.error === 'string'
? t(`shared.translate.${data.error}`)
: t('shared.translate.succeed', {
? t(`componentTimeline:shared.translate.${data.error}` as any)
: t('componentTimeline:shared.translate.succeed', {
provider: data?.provider,
source: data?.sourceLanguage
})
: t('shared.translate.default')}
: t('componentTimeline:shared.translate.default')}
</CustomText>
{isFetching ? (
<Circle

View File

@ -39,7 +39,7 @@ const menuAccount = ({
const navigation =
useNavigation<NativeStackNavigationProp<TabSharedStackParamList, any, undefined>>()
const { t } = useTranslation('componentContextMenu')
const { t } = useTranslation(['common', 'componentContextMenu', 'componentRelationship'])
const menus: ContextMenu[][] = [[]]
@ -62,11 +62,15 @@ const menuAccount = ({
displayMessage({
type: 'success',
message: t('common:message.success.message', {
function: t(`account.${theParams.payload.property}.action`, {
...(theParams.payload.property !== 'reports' && {
context: (theParams.payload.currentValue || false).toString()
})
})
function: t(
`componentContextMenu:account.${theParams.payload.property}.action`,
theParams.payload.property !== 'reports'
? {
defaultValue: 'false',
context: (theParams.payload.currentValue || false).toString()
}
: { defaultValue: 'false' }
)
})
})
},
@ -75,11 +79,15 @@ const menuAccount = ({
displayMessage({
type: 'danger',
message: t('common:message.error.message', {
function: t(`account.${theParams.payload.property}.action`, {
...(theParams.payload.property !== 'reports' && {
context: (theParams.payload.currentValue || false).toString()
})
})
function: t(
`componentContextMenu:account.${theParams.payload.property}.action`,
theParams.payload.property !== 'reports'
? {
defaultValue: 'false',
context: (theParams.payload.currentValue || false).toString()
}
: { defaultValue: 'false' }
)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -109,7 +117,7 @@ const menuAccount = ({
displayMessage({
type: 'danger',
message: t('common:message.error.message', {
function: t(`${action}.function`)
function: t(`componentContextMenu:${action}.function` as any)
}),
...(err.status &&
typeof err.status === 'number' &&
@ -138,7 +146,8 @@ const menuAccount = ({
hidden: false
},
title: !data?.requested
? t('account.following.action', {
? t('componentContextMenu:account.following.action', {
defaultValue: 'false',
context: (data?.following || false).toString()
})
: t('componentRelationship:button.requested'),
@ -158,7 +167,7 @@ const menuAccount = ({
destructive: false,
hidden: !isFetched || !data?.following
},
title: t('account.inLists'),
title: t('componentContextMenu:account.inLists'),
icon: 'checklist'
})
menus[0].push({
@ -175,7 +184,8 @@ const menuAccount = ({
destructive: false,
hidden: false
},
title: t('account.mute.action', {
title: t('componentContextMenu:account.mute.action', {
defaultValue: 'false',
context: (data?.muting || false).toString()
}),
icon: data?.muting ? 'eye' : 'eye.slash'
@ -188,27 +198,32 @@ const menuAccount = ({
key: 'account-block',
item: {
onSelect: () =>
Alert.alert(t('account.block.alert.title', { username: account.username }), undefined, [
{
text: t('common:buttons.confirm'),
style: 'destructive',
onPress: () =>
timelineMutation.mutate({
type: 'updateAccountProperty',
queryKey,
id: account.id,
payload: { property: 'block', currentValue: data?.blocking }
})
},
{
text: t('common:buttons.cancel')
}
]),
Alert.alert(
t('componentContextMenu:account.block.alert.title', { username: account.username }),
undefined,
[
{
text: t('common:buttons.confirm'),
style: 'destructive',
onPress: () =>
timelineMutation.mutate({
type: 'updateAccountProperty',
queryKey,
id: account.id,
payload: { property: 'block', currentValue: data?.blocking }
})
},
{
text: t('common:buttons.cancel')
}
]
),
disabled: Platform.OS !== 'android' ? !data || !isFetched : false,
destructive: !data?.blocking,
hidden: false
},
title: t('account.block.action', {
title: t('componentContextMenu:account.block.action', {
defaultValue: 'false',
context: (data?.blocking || false).toString()
}),
icon: data?.blocking ? 'checkmark.circle' : 'xmark.circle'
@ -221,7 +236,7 @@ const menuAccount = ({
destructive: true,
hidden: false
},
title: t('account.reports.action'),
title: t('componentContextMenu:account.reports.action'),
icon: 'flag'
}
])

View File

@ -17,7 +17,7 @@ const menuInstance = ({
}): ContextMenu[][] => {
if (!status || !queryKey) return []
const { t } = useTranslation('componentContextMenu')
const { t } = useTranslation(['common', 'componentContextMenu'])
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
@ -25,7 +25,7 @@ const menuInstance = ({
displayMessage({
type: 'success',
message: t('common:message.success.message', {
function: t(`instance.block.action`, { instance })
function: t(`componentContextMenu:instance.block.action`, { instance })
})
})
queryClient.invalidateQueries(queryKey)
@ -45,8 +45,8 @@ const menuInstance = ({
item: {
onSelect: () =>
Alert.alert(
t('instance.block.alert.title', { instance }),
t('instance.block.alert.message'),
t('componentContextMenu:instance.block.alert.title', { instance }),
t('componentContextMenu:instance.block.alert.message'),
[
{
text: t('common:buttons.confirm'),
@ -68,7 +68,7 @@ const menuInstance = ({
destructive: true,
hidden: false
},
title: t('instance.block.action', { instance }),
title: t('componentContextMenu:instance.block.action', { instance }),
icon: ''
}
])

View File

@ -28,7 +28,7 @@ const menuStatus = ({
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList, 'Screen-Tabs'>>()
const { theme } = useTheme()
const { t } = useTranslation('componentContextMenu')
const { t } = useTranslation(['common', 'componentContextMenu'])
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
@ -41,7 +41,7 @@ const menuStatus = ({
theme,
type: 'error',
message: t('common:message.error.message', {
function: t(`status.${theFunction}.action`)
function: t(`componentContextMenu:status.${theFunction}.action` as any)
}),
...(err?.status &&
typeof err.status === 'number' &&
@ -100,81 +100,89 @@ const menuStatus = ({
destructive: false,
hidden: !canEditPost
},
title: t('status.edit.action'),
title: t('componentContextMenu:status.edit.action'),
icon: 'square.and.pencil'
},
{
key: 'status-delete-edit',
item: {
onSelect: () =>
Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
{
text: t('common:buttons.confirm'),
style: 'destructive',
onPress: async () => {
let replyToStatus: Mastodon.Status | undefined = undefined
if (status.in_reply_to_id) {
replyToStatus = await apiInstance<Mastodon.Status>({
method: 'get',
url: `statuses/${status.in_reply_to_id}`
}).then(res => res.body)
}
mutation
.mutateAsync({
type: 'deleteItem',
source: 'statuses',
queryKey,
id: status.id
})
.then(res => {
navigation.navigate('Screen-Compose', {
type: 'deleteEdit',
incomingStatus: res.body as Mastodon.Status,
...(replyToStatus && { replyToStatus }),
queryKey
Alert.alert(
t('componentContextMenu:status.deleteEdit.alert.title'),
t('componentContextMenu:status.deleteEdit.alert.message'),
[
{
text: t('common:buttons.confirm'),
style: 'destructive',
onPress: async () => {
let replyToStatus: Mastodon.Status | undefined = undefined
if (status.in_reply_to_id) {
replyToStatus = await apiInstance<Mastodon.Status>({
method: 'get',
url: `statuses/${status.in_reply_to_id}`
}).then(res => res.body)
}
mutation
.mutateAsync({
type: 'deleteItem',
source: 'statuses',
queryKey,
id: status.id
})
})
.then(res => {
navigation.navigate('Screen-Compose', {
type: 'deleteEdit',
incomingStatus: res.body as Mastodon.Status,
...(replyToStatus && { replyToStatus }),
queryKey
})
})
}
},
{
text: t('common:buttons.cancel')
}
},
{
text: t('common:buttons.cancel')
}
]),
]
),
disabled: false,
destructive: true,
hidden: false
},
title: t('status.deleteEdit.action'),
title: t('componentContextMenu:status.deleteEdit.action'),
icon: 'pencil.and.outline'
},
{
key: 'status-delete',
item: {
onSelect: () =>
Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
{
text: t('common:buttons.confirm'),
style: 'destructive',
onPress: async () => {
mutation.mutate({
type: 'deleteItem',
source: 'statuses',
queryKey,
rootQueryKey,
id: status.id
})
Alert.alert(
t('componentContextMenu:status.delete.alert.title'),
t('componentContextMenu:status.delete.alert.message'),
[
{
text: t('common:buttons.confirm'),
style: 'destructive',
onPress: async () => {
mutation.mutate({
type: 'deleteItem',
source: 'statuses',
queryKey,
rootQueryKey,
id: status.id
})
}
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
]),
]
),
disabled: false,
destructive: true,
hidden: false
},
title: t('status.delete.action'),
title: t('componentContextMenu:status.delete.action'),
icon: 'trash'
}
])
@ -200,7 +208,8 @@ const menuStatus = ({
destructive: false,
hidden: false
},
title: t('status.mute.action', {
title: t('componentContextMenu:status.mute.action', {
defaultValue: 'false',
context: (status.muted || false).toString()
}),
icon: status.muted ? 'speaker' : 'speaker.slash'
@ -226,7 +235,8 @@ const menuStatus = ({
destructive: false,
hidden: status.visibility !== 'public' && status.visibility !== 'unlisted'
},
title: t('status.pin.action', {
title: t('componentContextMenu:status.pin.action', {
defaultValue: 'false',
context: (status.pinned || false).toString()
}),
icon: status.pinned ? 'pin.slash' : 'pin'

View File

@ -112,6 +112,7 @@ i18n.use(initReactI18next).init({
'zh-Hans': zh_Hans,
'zh-Hant': zh_Hant
},
returnNull: false,
returnEmptyString: false,
saveMissing: true,

View File

@ -16,17 +16,15 @@ export interface Props {
const ActionsAltText: React.FC<Props> = ({ text }) => {
const navigation = useNavigation()
const { t } = useTranslation('screenActions')
const { t } = useTranslation(['common', 'screenActions'])
const { colors } = useTheme()
return (
<>
<MenuContainer>
<MenuHeader heading={t(`content.altText.heading`)} />
<MenuHeader heading={t(`screenActions:content.altText.heading`)} />
<ScrollView style={{ maxHeight: Dimensions.get('window').height / 2 }}>
<CustomText style={{ color: colors.primaryDefault }}>
{text}
</CustomText>
<CustomText style={{ color: colors.primaryDefault }}>{text}</CustomText>
</ScrollView>
</MenuContainer>
<Button

View File

@ -87,7 +87,8 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
}}
>
<Trans
i18nKey='screenAnnouncements:content.published'
ns='screenAnnouncements'
i18nKey='content.published'
components={[<RelativeTime time={item.published_at} />]}
/>
</CustomText>

View File

@ -39,7 +39,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
route: { params },
navigation
}) => {
const { t } = useTranslation('screenCompose')
const { t } = useTranslation(['common', 'screenCompose'])
const { colors } = useTheme()
const queryClient = useQueryClient()
@ -212,9 +212,9 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
navigation.goBack()
return
} else {
Alert.alert(t('heading.left.alert.title'), undefined, [
Alert.alert(t('screenCompose:heading.left.alert.title'), undefined, [
{
text: t('heading.left.alert.buttons.delete'),
text: t('screenCompose:heading.left.alert.buttons.delete'),
style: 'destructive',
onPress: () => {
removeDraft()
@ -222,7 +222,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
}
},
{
text: t('heading.left.alert.buttons.save'),
text: t('screenCompose:heading.left.alert.buttons.save'),
onPress: () => {
saveDraft()
navigation.goBack()
@ -266,7 +266,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
: 'default'
: params.type)) ||
'default'
}`
}` as any
)}
onPress={() => {
composeDispatch({ type: 'posting', payload: true })
@ -302,8 +302,8 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
.catch(error => {
if (error?.removeReply) {
Alert.alert(
t('heading.right.alert.removeReply.title'),
t('heading.right.alert.removeReply.description'),
t('screenCompose:heading.right.alert.removeReply.title'),
t('screenCompose:heading.right.alert.removeReply.description'),
[
{
text: t('common:buttons.cancel'),
@ -313,7 +313,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
style: 'destructive'
},
{
text: t('heading.right.alert.removeReply.confirm'),
text: t('screenCompose:heading.right.alert.removeReply.confirm'),
onPress: () => {
composeDispatch({ type: 'removeReply' })
composeDispatch({ type: 'posting', payload: false })
@ -326,10 +326,8 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
haptics('Error')
handleError({ message: 'Posting error', captureResponse: true })
composeDispatch({ type: 'posting', payload: false })
Alert.alert(t('heading.right.alert.default.title'), undefined, [
{
text: t('heading.right.alert.default.button')
}
Alert.alert(t('screenCompose:heading.right.alert.default.title'), undefined, [
{ text: t('screenCompose:heading.right.alert.default.button') }
])
}
})

View File

@ -16,7 +16,7 @@ import chooseAndUploadAttachment from './Footer/addAttachment'
const ComposeActions: React.FC = () => {
const { showActionSheetWithOptions } = useActionSheet()
const { composeState, composeDispatch } = useContext(ComposeContext)
const { t } = useTranslation('screenCompose')
const { t } = useTranslation(['common', 'screenCompose'])
const { colors } = useTheme()
const instanceConfigurationStatusMaxAttachments = useSelector(
getInstanceConfigurationStatusMaxAttachments,
@ -81,12 +81,12 @@ const ComposeActions: React.FC = () => {
if (!composeState.visibilityLock) {
showActionSheetWithOptions(
{
title: t('content.root.actions.visibility.title'),
title: t('screenCompose:content.root.actions.visibility.title'),
options: [
t('content.root.actions.visibility.options.public'),
t('content.root.actions.visibility.options.unlisted'),
t('content.root.actions.visibility.options.private'),
t('content.root.actions.visibility.options.direct'),
t('screenCompose:content.root.actions.visibility.options.public'),
t('screenCompose:content.root.actions.visibility.options.unlisted'),
t('screenCompose:content.root.actions.visibility.options.private'),
t('screenCompose:content.root.actions.visibility.options.direct'),
t('common:buttons.cancel')
],
cancelButtonIndex: 4,
@ -160,8 +160,8 @@ const ComposeActions: React.FC = () => {
>
<Pressable
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.attachment.accessibilityLabel')}
accessibilityHint={t('content.root.actions.attachment.accessibilityHint')}
accessibilityLabel={t('screenCompose:content.root.actions.attachment.accessibilityLabel')}
accessibilityHint={t('screenCompose:content.root.actions.attachment.accessibilityHint')}
accessibilityState={{
disabled: composeState.poll.active
}}
@ -171,8 +171,8 @@ const ComposeActions: React.FC = () => {
/>
<Pressable
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.poll.accessibilityLabel')}
accessibilityHint={t('content.root.actions.poll.accessibilityHint')}
accessibilityLabel={t('screenCompose:content.root.actions.poll.accessibilityLabel')}
accessibilityHint={t('screenCompose:content.root.actions.poll.accessibilityHint')}
accessibilityState={{
disabled: composeState.attachments.uploads.length ? true : false,
expanded: composeState.poll.active
@ -183,7 +183,7 @@ const ComposeActions: React.FC = () => {
/>
<Pressable
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.visibility.accessibilityLabel', {
accessibilityLabel={t('screenCompose:content.root.actions.visibility.accessibilityLabel', {
visibility: composeState.visibility
})}
accessibilityState={{ disabled: composeState.visibilityLock }}
@ -199,7 +199,7 @@ const ComposeActions: React.FC = () => {
/>
<Pressable
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.spoiler.accessibilityLabel')}
accessibilityLabel={t('screenCompose:content.root.actions.spoiler.accessibilityLabel')}
accessibilityState={{ expanded: composeState.spoiler.active }}
style={styles.button}
onPress={spoilerOnPress}
@ -213,8 +213,8 @@ const ComposeActions: React.FC = () => {
/>
<Pressable
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.emoji.accessibilityLabel')}
accessibilityHint={t('content.root.actions.emoji.accessibilityHint')}
accessibilityLabel={t('screenCompose:content.root.actions.emoji.accessibilityLabel')}
accessibilityHint={t('screenCompose:content.root.actions.emoji.accessibilityHint')}
accessibilityState={{
disabled: emojis.current?.length ? false : true,
expanded: emojisState.targetIndex !== -1

View File

@ -21,7 +21,7 @@ const ComposePoll: React.FC = () => {
},
composeDispatch
} = useContext(ComposeContext)
const { t } = useTranslation('screenCompose')
const { t } = useTranslation(['common', 'screenCompose'])
const { colors, mode } = useTheme()
const instanceConfigurationPoll = useSelector(getInstanceConfigurationPoll, () => true)
@ -71,7 +71,7 @@ const ComposePoll: React.FC = () => {
/>
<TextInput
accessibilityLabel={t(
'content.root.footer.poll.option.placeholder.accessibilityLabel',
'screenCompose:content.root.footer.poll.option.placeholder.accessibilityLabel',
{ index: i + 1 }
)}
keyboardAppearance={mode}
@ -88,8 +88,8 @@ const ComposePoll: React.FC = () => {
}}
placeholder={
multiple
? t('content.root.footer.poll.option.placeholder.multiple')
: t('content.root.footer.poll.option.placeholder.single')
? t('screenCompose:content.root.footer.poll.option.placeholder.multiple')
: t('screenCompose:content.root.footer.poll.option.placeholder.single')
}
placeholderTextColor={colors.disabled}
maxLength={MAX_CHARS_PER_OPTION}
@ -119,14 +119,15 @@ const ComposePoll: React.FC = () => {
{...(total > 2
? {
accessibilityLabel: t(
'content.root.footer.poll.quantity.reduce.accessibilityLabel',
'screenCompose:content.root.footer.poll.quantity.reduce.accessibilityLabel',
{ amount: total - 1 }
)
}
: {
accessibilityHint: t('content.root.footer.poll.quantity.reduce.accessibilityHint', {
amount: total
})
accessibilityHint: t(
'screenCompose:content.root.footer.poll.quantity.reduce.accessibilityHint',
{ amount: total }
)
})}
onPress={() => {
total > 2 &&
@ -152,13 +153,13 @@ const ComposePoll: React.FC = () => {
{...(total < MAX_OPTIONS
? {
accessibilityLabel: t(
'content.root.footer.poll.quantity.increase.accessibilityLabel',
'screenCompose:content.root.footer.poll.quantity.increase.accessibilityLabel',
{ amount: total + 1 }
)
}
: {
accessibilityHint: t(
'content.root.footer.poll.quantity.increase.accessibilityHint',
'screenCompose:content.root.footer.poll.quantity.increase.accessibilityHint',
{ amount: total }
)
})}
@ -177,18 +178,18 @@ const ComposePoll: React.FC = () => {
</View>
<View style={{ paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }}>
<MenuRow
title={t('content.root.footer.poll.multiple.heading')}
title={t('screenCompose:content.root.footer.poll.multiple.heading')}
content={
multiple
? t('content.root.footer.poll.multiple.options.multiple')
: t('content.root.footer.poll.multiple.options.single')
? t('screenCompose:content.root.footer.poll.multiple.options.multiple')
: t('screenCompose:content.root.footer.poll.multiple.options.single')
}
onPress={() =>
showActionSheetWithOptions(
{
options: [
t('content.root.footer.poll.multiple.options.single'),
t('content.root.footer.poll.multiple.options.multiple'),
t('screenCompose:content.root.footer.poll.multiple.options.single'),
t('screenCompose:content.root.footer.poll.multiple.options.multiple'),
t('common:buttons.cancel')
],
cancelButtonIndex: 2,
@ -207,8 +208,8 @@ const ComposePoll: React.FC = () => {
iconBack='ChevronRight'
/>
<MenuRow
title={t('content.root.footer.poll.expiration.heading')}
content={t(`content.root.footer.poll.expiration.options.${expire}`)}
title={t('screenCompose:content.root.footer.poll.expiration.heading')}
content={t(`screenCompose:content.root.footer.poll.expiration.options.${expire}`)}
onPress={() => {
const expirations = [
'300',
@ -225,7 +226,9 @@ const ComposePoll: React.FC = () => {
showActionSheetWithOptions(
{
options: [
...expirations.map(e => t(`content.root.footer.poll.expiration.options.${e}`)),
...expirations.map(e =>
t(`screenCompose:content.root.footer.poll.expiration.options.${e}` as any)
),
t('common:buttons.cancel')
],
cancelButtonIndex: expirations.length,

View File

@ -41,7 +41,7 @@ const ScreenImagesViewer = ({
const insets = useSafeAreaInsets()
const { mode, colors } = useTheme()
const { t } = useTranslation('screenImageViewer')
const { t } = useTranslation(['common', 'screenImageViewer'])
const initialIndex = imageUrls.findIndex(image => image.id === id)
const [currentIndex, setCurrentIndex] = useState(initialIndex)
@ -51,8 +51,8 @@ const ScreenImagesViewer = ({
showActionSheetWithOptions(
{
options: [
t('content.options.save'),
t('content.options.share'),
t('screenImageViewer:content.options.save'),
t('screenImageViewer:content.options.share'),
t('common:buttons.cancel')
],
cancelButtonIndex: 2,
@ -164,8 +164,8 @@ const ScreenImagesViewer = ({
<HeaderCenter inverted content={`${currentIndex + 1} / ${imageUrls.length}`} />
) : null}
<HeaderRight
accessibilityLabel={t('content.actions.accessibilityLabel')}
accessibilityHint={t('content.actions.accessibilityHint')}
accessibilityLabel={t('screenImageViewer:content.actions.accessibilityLabel')}
accessibilityHint={t('screenImageViewer:content.actions.accessibilityHint')}
content='MoreHorizontal'
native={false}
background
@ -177,8 +177,8 @@ const ScreenImagesViewer = ({
showActionSheetWithOptions(
{
options: [
t('content.options.save'),
t('content.options.share'),
t('screenImageViewer:content.options.save'),
t('screenImageViewer:content.options.share'),
t('common:buttons.cancel')
],
cancelButtonIndex: 2,

View File

@ -12,7 +12,7 @@ import { FlatList } from 'react-native-gesture-handler'
const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>> = ({
navigation
}) => {
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const { data, fetchNextPage, refetch } = useFollowedTagsQuery()
const flattenData = data?.pages ? data.pages.flatMap(page => [...page.body]) : []
@ -31,7 +31,9 @@ const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>>
displayMessage({
type: 'error',
message: t('common:message.error.message', {
function: to ? t('shared.hashtag.follow') : t('shared.hashtag.unfollow')
function: to
? t('screenTabs:shared.hashtag.follow')
: t('screenTabs:shared.hashtag.unfollow')
}),
...(err.status &&
typeof err.status === 'number' &&
@ -55,7 +57,7 @@ const TabMeFollowedTags: React.FC<TabMeStackScreenProps<'Tab-Me-FollowedTags'>>
children={
<Button
type='text'
content={t('shared.hashtag.unfollow')}
content={t('screenTabs:shared.hashtag.unfollow')}
onPress={() => mutation.mutate({ tag: item.name, to: !item.following })}
/>
}

View File

@ -19,7 +19,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
route: { params }
}) => {
const { colors, theme } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const queryKey: QueryKeyListAccounts = ['ListAccounts', { id: params.id }]
const { data, refetch, fetchNextPage, hasNextPage } = useListAccountsQuery({
@ -45,7 +45,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
displayMessage({
type: 'danger',
message: t('common:message.error.message', {
function: t('me.listAccounts.error')
function: t('screenTabs:me.listAccounts.error')
})
})
}
@ -88,7 +88,7 @@ const TabMeListAccounts: React.FC<TabMeStackScreenProps<'Tab-Me-List-Accounts'>>
color: colors.secondary
}}
>
{t('me.listAccounts.empty')}
{t('screenTabs:me.listAccounts.empty')}
</CustomText>
</View>
}

View File

@ -20,7 +20,7 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
route: { params }
}) => {
const { colors, theme } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const messageRef = useRef(null)
@ -44,7 +44,9 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
type: 'danger',
message: t('common:message.error.message', {
function:
params.type === 'add' ? t('me.stacks.listAdd.name') : t('me.stacks.listEdit.name')
params.type === 'add'
? t('screenTabs:me.stacks.listAdd.name')
: t('screenTabs:me.stacks.listEdit.name')
})
})
}
@ -65,24 +67,27 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
>([
{
id: 'none',
content: t('me.listEdit.repliesPolicy.options.none'),
content: t('screenTabs:me.listEdit.repliesPolicy.options.none'),
selected: params.type === 'edit' ? params.payload.replies_policy === 'none' : false
},
{
id: 'list',
content: t('me.listEdit.repliesPolicy.options.list'),
content: t('screenTabs:me.listEdit.repliesPolicy.options.list'),
selected: params.type === 'edit' ? params.payload.replies_policy === 'list' : true
},
{
id: 'followed',
content: t('me.listEdit.repliesPolicy.options.followed'),
content: t('screenTabs:me.listEdit.repliesPolicy.options.followed'),
selected: params.type === 'edit' ? params.payload.replies_policy === 'followed' : false
}
])
useEffect(() => {
navigation.setOptions({
title: params.type === 'add' ? t('me.stacks.listAdd.name') : t('me.stacks.listEdit.name'),
title:
params.type === 'add'
? t('screenTabs:me.stacks.listAdd.name')
: t('screenTabs:me.stacks.listEdit.name'),
headerLeft: () => (
<HeaderLeft
content='X'
@ -140,7 +145,7 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
return (
<ScrollView style={{ paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }}>
<ComponentInput {...inputProps} autoFocus title={t('me.listEdit.title')} />
<ComponentInput {...inputProps} autoFocus title={t('screenTabs:me.listEdit.title')} />
<CustomText
fontStyle='M'
@ -151,7 +156,7 @@ const TabMeListEdit: React.FC<TabMeStackScreenProps<'Tab-Me-List-Edit'>> = ({
marginTop: StyleConstants.Spacing.M
}}
>
{t('me.listEdit.repliesPolicy.heading')}
{t('screenTabs:me.listEdit.repliesPolicy.heading')}
</CustomText>
<Selections options={options} setOptions={setOptions} />

View File

@ -14,7 +14,7 @@ const TabMeListList: React.FC<TabMeStackScreenProps<'Tab-Me-List-List'>> = ({ na
headerRight: () => (
<HeaderRight
type='text'
content={t('common:buttons.create')}
content={t('buttons.create')}
onPress={() => navigation.navigate('Tab-Me-List-Edit', { type: 'add' })}
/>
)

View File

@ -18,7 +18,7 @@ const TabMeList: React.FC<TabMeStackScreenProps<'Tab-Me-List'>> = ({
route: { key, params }
}) => {
const { colors } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'List', list: params.id }]
const queryKeyLists: QueryKeyLists = ['Lists']
@ -32,7 +32,7 @@ const TabMeList: React.FC<TabMeStackScreenProps<'Tab-Me-List'>> = ({
displayMessage({
type: 'danger',
message: t('common:message.error.message', {
function: t('me.listDelete.heading')
function: t('screenTabs:me.listDelete.heading')
})
})
}

View File

@ -19,7 +19,7 @@ const Field: React.FC<{
field?: Mastodon.Field
}> = ({ allProps, setDirty, index, field }) => {
const { colors } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const nameRef = useRef<TextInput>(null)
const valueRef = useRef<TextInput>(null)
@ -55,11 +55,11 @@ const Field: React.FC<{
color: colors.primaryDefault
}}
>
{t('me.profile.fields.group', { index: index + 1 })}
{t('screenTabs:me.profile.fields.group', { index: index + 1 })}
</CustomText>
<ComponentInput title={t('me.profile.fields.label')} {...allProps[index * 2]} />
<ComponentInput title={t('screenTabs:me.profile.fields.label')} {...allProps[index * 2]} />
<ComponentInput
title={t('me.profile.fields.content')}
title={t('screenTabs:me.profile.fields.content')}
{...allProps[index * 2 + 1]}
multiline
/>
@ -79,7 +79,7 @@ const TabMeProfileFields: React.FC<
navigation
}) => {
const { theme } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common'])
const { mutateAsync, status } = useProfileMutation()
const allProps: EmojisState['inputProps'] = []
@ -93,21 +93,17 @@ const TabMeProfileFields: React.FC<
content='X'
onPress={() => {
if (dirty) {
Alert.alert(
t('common:discard.title'),
t('common:discard.message'),
[
{
text: t('common:buttons.discard'),
style: 'destructive',
onPress: () => navigation.navigate('Tab-Me-Profile-Root')
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
]
)
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
{
text: t('common:buttons.discard'),
style: 'destructive',
onPress: () => navigation.navigate('Tab-Me-Profile-Root')
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
])
} else {
navigation.navigate('Tab-Me-Profile-Root')
}

View File

@ -23,7 +23,7 @@ const TabMeProfileName: React.FC<
navigation
}) => {
const { theme } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common'])
const { mutateAsync, status } = useProfileMutation()
const [value, setValue] = useState(display_name)
@ -47,21 +47,17 @@ const TabMeProfileName: React.FC<
content='X'
onPress={() => {
if (dirty) {
Alert.alert(
t('common:discard.title'),
t('common:discard.message'),
[
{
text: t('common:buttons.discard'),
style: 'destructive',
onPress: () => navigation.navigate('Tab-Me-Profile-Root')
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
]
)
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
{
text: t('common:buttons.discard'),
style: 'destructive',
onPress: () => navigation.navigate('Tab-Me-Profile-Root')
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
])
} else {
navigation.navigate('Tab-Me-Profile-Root')
}

View File

@ -23,7 +23,7 @@ const TabMeProfileNote: React.FC<
navigation
}) => {
const { theme } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common'])
const { mutateAsync, status } = useProfileMutation()
const [notes, setNotes] = useState(note)
@ -47,21 +47,17 @@ const TabMeProfileNote: React.FC<
content='X'
onPress={() => {
if (dirty) {
Alert.alert(
t('common:discard.title'),
t('common:discard.message'),
[
{
text: t('common:buttons.discard'),
style: 'destructive',
onPress: () => navigation.navigate('Tab-Me-Profile-Root')
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
]
)
Alert.alert(t('common:discard.title'), t('common:discard.message'), [
{
text: t('common:buttons.discard'),
style: 'destructive',
onPress: () => navigation.navigate('Tab-Me-Profile-Root')
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
])
} else {
navigation.navigate('Tab-Me-Profile-Root')
}

View File

@ -18,7 +18,7 @@ const TabMeProfileRoot: React.FC<
}
> = ({ messageRef, navigation }) => {
const { colors } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const { showActionSheetWithOptions } = useActionSheet()
@ -30,7 +30,7 @@ const TabMeProfileRoot: React.FC<
<ScrollView>
<MenuContainer>
<MenuRow
title={t('me.profile.root.name.title')}
title={t('screenTabs:me.profile.root.name.title')}
content={data?.display_name}
loading={isFetching}
iconBack='ChevronRight'
@ -44,7 +44,7 @@ const TabMeProfileRoot: React.FC<
<ProfileAvatarHeader type='avatar' messageRef={messageRef} />
<ProfileAvatarHeader type='header' messageRef={messageRef} />
<MenuRow
title={t('me.profile.root.note.title')}
title={t('screenTabs:me.profile.root.note.title')}
content={data?.source.note}
loading={isFetching}
iconBack='ChevronRight'
@ -56,10 +56,10 @@ const TabMeProfileRoot: React.FC<
}}
/>
<MenuRow
title={t('me.profile.root.fields.title')}
title={t('screenTabs:me.profile.root.fields.title')}
content={
data?.source.fields && data.source.fields.length
? t('me.profile.root.fields.total', {
? t('screenTabs:me.profile.root.fields.total', {
count: data.source.fields.length
})
: undefined
@ -74,58 +74,60 @@ const TabMeProfileRoot: React.FC<
/>
</MenuContainer>
<MenuContainer>
<MenuRow
title={t('me.profile.root.visibility.title')}
content={
data?.source.privacy
? t(`me.profile.root.visibility.options.${data?.source.privacy}`)
: undefined
}
loading={isFetching}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('me.profile.root.visibility.title'),
options: [
t('me.profile.root.visibility.options.public'),
t('me.profile.root.visibility.options.unlisted'),
t('me.profile.root.visibility.options.private'),
t('common:buttons.cancel')
],
cancelButtonIndex: 3,
...androidActionSheetStyles(colors)
},
async buttonIndex => {
switch (buttonIndex) {
case 0:
case 1:
case 2:
const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [
'public',
'unlisted',
'private'
]
if (data?.source.privacy !== indexVisibilityMapping[buttonIndex]) {
mutateAsync({
messageRef,
message: {
text: 'me.profile.root.visibility.title',
succeed: false,
failed: true
},
type: 'source[privacy]',
data: indexVisibilityMapping[buttonIndex]
}).then(() => dispatch(updateAccountPreferences()))
}
break
{data?.source.privacy !== 'direct' ? (
<MenuRow
title={t('screenTabs:me.profile.root.visibility.title')}
content={
data?.source.privacy
? t(`screenTabs:me.profile.root.visibility.options.${data.source.privacy}`)
: undefined
}
loading={isFetching}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('screenTabs:me.profile.root.visibility.title'),
options: [
t('screenTabs:me.profile.root.visibility.options.public'),
t('screenTabs:me.profile.root.visibility.options.unlisted'),
t('screenTabs:me.profile.root.visibility.options.private'),
t('common:buttons.cancel')
],
cancelButtonIndex: 3,
...androidActionSheetStyles(colors)
},
async buttonIndex => {
switch (buttonIndex) {
case 0:
case 1:
case 2:
const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [
'public',
'unlisted',
'private'
]
if (data?.source.privacy !== indexVisibilityMapping[buttonIndex]) {
mutateAsync({
messageRef,
message: {
text: 'me.profile.root.visibility.title',
succeed: false,
failed: true
},
type: 'source[privacy]',
data: indexVisibilityMapping[buttonIndex]
}).then(() => dispatch(updateAccountPreferences()))
}
break
}
}
}
)
}
/>
)
}
/>
) : null}
<MenuRow
title={t('me.profile.root.sensitive.title')}
title={t('screenTabs:me.profile.root.sensitive.title')}
switchValue={data?.source.sensitive}
switchOnValueChange={() =>
mutateAsync({
@ -144,8 +146,8 @@ const TabMeProfileRoot: React.FC<
</MenuContainer>
<MenuContainer>
<MenuRow
title={t('me.profile.root.lock.title')}
description={t('me.profile.root.lock.description')}
title={t('screenTabs:me.profile.root.lock.title')}
description={t('screenTabs:me.profile.root.lock.description')}
switchValue={data?.locked}
switchOnValueChange={() =>
mutateAsync({
@ -162,8 +164,8 @@ const TabMeProfileRoot: React.FC<
loading={isFetching}
/>
<MenuRow
title={t('me.profile.root.bot.title')}
description={t('me.profile.root.bot.description')}
title={t('screenTabs:me.profile.root.bot.title')}
description={t('screenTabs:me.profile.root.bot.description')}
switchValue={data?.bot}
switchOnValueChange={() =>
mutateAsync({

View File

@ -13,7 +13,7 @@ export interface Props {
}
const ProfileAvatarHeader: React.FC<Props> = ({ type, messageRef }) => {
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['screenTabs'])
const { showActionSheetWithOptions } = useActionSheet()
@ -22,8 +22,8 @@ const ProfileAvatarHeader: React.FC<Props> = ({ type, messageRef }) => {
return (
<MenuRow
title={t(`me.profile.root.${type}.title`)}
description={t(`me.profile.root.${type}.description`)}
title={t(`screenTabs:me.profile.root.${type}.title`)}
description={t(`screenTabs:me.profile.root.${type}.description`)}
loading={query.isFetching || mutation.isLoading}
iconBack='ChevronRight'
onPress={async () => {

View File

@ -10,12 +10,12 @@ import {
updateInstanceMePage
} from '@utils/slices/instancesSlice'
import { getInstancePush } from '@utils/slices/instancesSlice'
import React, { useEffect } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
const Collections: React.FC = () => {
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['screenAnnouncements', 'screenTabs'])
const navigation = useNavigation<any>()
const dispatch = useAppDispatch()
@ -65,26 +65,26 @@ const Collections: React.FC = () => {
<MenuRow
iconFront='Mail'
iconBack='ChevronRight'
title={t('me.stacks.conversations.name')}
title={t('screenTabs:me.stacks.conversations.name')}
onPress={() => navigation.navigate('Tab-Me-Conversations')}
/>
<MenuRow
iconFront='Bookmark'
iconBack='ChevronRight'
title={t('me.stacks.bookmarks.name')}
title={t('screenTabs:me.stacks.bookmarks.name')}
onPress={() => navigation.navigate('Tab-Me-Bookmarks')}
/>
<MenuRow
iconFront='Heart'
iconBack='ChevronRight'
title={t('me.stacks.favourites.name')}
title={t('screenTabs:me.stacks.favourites.name')}
onPress={() => navigation.navigate('Tab-Me-Favourites')}
/>
{mePage.lists.shown ? (
<MenuRow
iconFront='List'
iconBack='ChevronRight'
title={t('me.stacks.lists.name')}
title={t('screenTabs:me.stacks.lists.name')}
onPress={() => navigation.navigate('Tab-Me-List-List')}
/>
) : null}
@ -92,7 +92,7 @@ const Collections: React.FC = () => {
<MenuRow
iconFront='Hash'
iconBack='ChevronRight'
title={t('me.stacks.followedTags.name')}
title={t('screenTabs:me.stacks.followedTags.name')}
onPress={() => navigation.navigate('Tab-Me-FollowedTags')}
/>
) : null}
@ -103,10 +103,10 @@ const Collections: React.FC = () => {
title={t('screenAnnouncements:heading')}
content={
mePage.announcements.unread
? t('me.root.announcements.content.unread', {
? t('screenTabs:me.root.announcements.content.unread', {
amount: mePage.announcements.unread
})
: t('me.root.announcements.content.read')
: t('screenTabs:me.root.announcements.content.read')
}
onPress={() => navigation.navigate('Screen-Announcements', { showAll: true })}
/>
@ -114,10 +114,13 @@ const Collections: React.FC = () => {
<MenuRow
iconFront={instancePush ? 'Bell' : 'BellOff'}
iconBack='ChevronRight'
title={t('me.stacks.push.name')}
title={t('screenTabs:me.stacks.push.name')}
content={
typeof instancePush.global === 'boolean'
? t('me.root.push.content', { context: instancePush.global.toString() })
? t('screenTabs:me.root.push.content', {
defaultValue: 'false',
context: instancePush.global.toString()
})
: undefined
}
onPress={() => navigation.navigate('Tab-Me-Push')}

View File

@ -11,7 +11,7 @@ import { useQueryClient } from '@tanstack/react-query'
import { useSelector } from 'react-redux'
const Logout: React.FC = () => {
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const dispatch = useAppDispatch()
const queryClient = useQueryClient()
const instance = useSelector(getInstance)
@ -19,7 +19,7 @@ const Logout: React.FC = () => {
return (
<Button
type='text'
content={t('me.root.logout.button')}
content={t('screenTabs:me.root.logout.button')}
style={{
marginHorizontal: StyleConstants.Spacing.Global.PagePadding * 2,
marginTop: StyleConstants.Spacing.Global.PagePadding,
@ -27,23 +27,27 @@ const Logout: React.FC = () => {
}}
destructive
onPress={() =>
Alert.alert(t('me.root.logout.alert.title'), t('me.root.logout.alert.message'), [
{
text: t('me.root.logout.alert.buttons.logout'),
style: 'destructive',
onPress: () => {
if (instance) {
haptics('Success')
queryClient.clear()
dispatch(removeInstance(instance))
Alert.alert(
t('screenTabs:me.root.logout.alert.title'),
t('screenTabs:me.root.logout.alert.message'),
[
{
text: t('screenTabs:me.root.logout.alert.buttons.logout'),
style: 'destructive',
onPress: () => {
if (instance) {
haptics('Success')
queryClient.clear()
dispatch(removeInstance(instance))
}
}
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
},
{
text: t('common:buttons.cancel'),
style: 'default'
}
])
]
)
}
/>
)

View File

@ -29,7 +29,7 @@ const SettingsApp: React.FC = () => {
const dispatch = useAppDispatch()
const { showActionSheetWithOptions } = useActionSheet()
const { colors } = useTheme()
const { t, i18n } = useTranslation('screenTabs')
const { t, i18n } = useTranslation(['common', 'screenTabs'])
const settingsFontsize = useSelector(getSettingsFontsize)
const settingsTheme = useSelector(getSettingsTheme)
@ -40,13 +40,15 @@ const SettingsApp: React.FC = () => {
return (
<MenuContainer>
<MenuRow
title={t('me.settings.fontsize.heading')}
content={t(`me.settings.fontsize.content.${mapFontsizeToName(settingsFontsize)}`)}
title={t('screenTabs:me.settings.fontsize.heading')}
content={t(
`screenTabs:me.settings.fontsize.content.${mapFontsizeToName(settingsFontsize)}`
)}
iconBack='ChevronRight'
onPress={() => navigation.navigate('Tab-Me-Settings-Fontsize')}
/>
<MenuRow
title={t('me.settings.language.heading')}
title={t('screenTabs:me.settings.language.heading')}
content={
// @ts-ignore
LOCALES[
@ -61,17 +63,17 @@ const SettingsApp: React.FC = () => {
}
/>
<MenuRow
title={t('me.settings.theme.heading')}
content={t(`me.settings.theme.options.${settingsTheme}`)}
title={t('screenTabs:me.settings.theme.heading')}
content={t(`screenTabs:me.settings.theme.options.${settingsTheme}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('me.settings.theme.heading'),
title: t('screenTabs:me.settings.theme.heading'),
options: [
t('me.settings.theme.options.auto'),
t('me.settings.theme.options.light'),
t('me.settings.theme.options.dark'),
t('screenTabs:me.settings.theme.options.auto'),
t('screenTabs:me.settings.theme.options.light'),
t('screenTabs:me.settings.theme.options.dark'),
t('common:buttons.cancel')
],
cancelButtonIndex: 3,
@ -97,16 +99,16 @@ const SettingsApp: React.FC = () => {
}
/>
<MenuRow
title={t('me.settings.darkTheme.heading')}
content={t(`me.settings.darkTheme.options.${settingsDarkTheme}`)}
title={t('screenTabs:me.settings.darkTheme.heading')}
content={t(`screenTabs:me.settings.darkTheme.options.${settingsDarkTheme}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('me.settings.darkTheme.heading'),
title: t('screenTabs:me.settings.darkTheme.heading'),
options: [
t('me.settings.darkTheme.options.lighter'),
t('me.settings.darkTheme.options.darker'),
t('screenTabs:me.settings.darkTheme.options.lighter'),
t('screenTabs:me.settings.darkTheme.options.darker'),
t('common:buttons.cancel')
],
cancelButtonIndex: 2,
@ -128,16 +130,16 @@ const SettingsApp: React.FC = () => {
}
/>
<MenuRow
title={t('me.settings.browser.heading')}
content={t(`me.settings.browser.options.${settingsBrowser}`)}
title={t('screenTabs:me.settings.browser.heading')}
content={t(`screenTabs:me.settings.browser.options.${settingsBrowser}`)}
iconBack='ChevronRight'
onPress={() =>
showActionSheetWithOptions(
{
title: t('me.settings.browser.heading'),
title: t('screenTabs:me.settings.browser.heading'),
options: [
t('me.settings.browser.options.internal'),
t('me.settings.browser.options.external'),
t('screenTabs:me.settings.browser.options.internal'),
t('screenTabs:me.settings.browser.options.external'),
t('common:buttons.cancel')
],
cancelButtonIndex: 2,
@ -159,8 +161,8 @@ const SettingsApp: React.FC = () => {
}
/>
<MenuRow
title={t('me.settings.staticEmoji.heading')}
description={t('me.settings.staticEmoji.description')}
title={t('screenTabs:me.settings.staticEmoji.heading')}
description={t('screenTabs:me.settings.staticEmoji.description')}
switchValue={settingsStaticEmoji}
switchOnValueChange={() => dispatch(changeStaticEmoji(!settingsStaticEmoji))}
/>

View File

@ -20,7 +20,7 @@ import { useSelector } from 'react-redux'
const TabNotificationsFilters: React.FC<
TabNotificationsStackScreenProps<'Tab-Notifications-Filters'>
> = ({ navigation }) => {
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const pushFeatures = usePushFeatures()
@ -33,7 +33,7 @@ const TabNotificationsFilters: React.FC<
useEffect(() => {
const changed = !isEqual(instanceNotificationsFilter, filters)
navigation.setOptions({
title: t('notifications.filters.title'),
title: t('screenTabs:notifications.filters.title'),
headerLeft: () => (
<HeaderLeft
content='ChevronDown'
@ -81,7 +81,7 @@ const TabNotificationsFilters: React.FC<
{PUSH_DEFAULT(pushFeatures).map((type, index) => (
<MenuRow
key={index}
title={t(`notifications.filters.options.${type}`)}
title={t(`screenTabs:notifications.filters.options.${type}`)}
switchValue={filters[type]}
switchOnValueChange={() => setFilters({ ...filters, [type]: !filters[type] })}
/>
@ -89,7 +89,7 @@ const TabNotificationsFilters: React.FC<
{PUSH_ADMIN(pushFeatures, profileQuery.data?.role?.permissions).map(({ type }) => (
<MenuRow
key={type}
title={t(`notifications.filters.options.${type}`)}
title={t(`screenTabs:notifications.filters.options.${type}`)}
switchValue={filters[type]}
switchOnValueChange={() => setFilters({ ...filters, [type]: !filters[type] })}
/>

View File

@ -21,12 +21,12 @@ const TabSharedAccountInLists: React.FC<
}
}) => {
const { colors } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
useEffect(() => {
navigation.setOptions({
presentation: 'modal',
title: t('shared.accountInLists.name', { username: account.username }),
title: t('screenTabs:shared.accountInLists.name', { username: account.username }),
headerRight: () => {
return (
<HeaderRight
@ -43,10 +43,14 @@ const TabSharedAccountInLists: React.FC<
const accountInListsQuery = useAccountInListsQuery({ id: account.id })
const sections = [
{ id: 'in', title: t('shared.accountInLists.inLists'), data: accountInListsQuery.data || [] },
{
id: 'in',
title: t('screenTabs:shared.accountInLists.inLists'),
data: accountInListsQuery.data || []
},
{
id: 'out',
title: t('shared.accountInLists.notInLists'),
title: t('screenTabs:shared.accountInLists.notInLists'),
data:
listsQuery.data?.filter(({ id }) =>
accountInListsQuery.data?.length

View File

@ -23,7 +23,8 @@ const TabSharedAttachments: React.FC<TabSharedStackScreenProps<'Tab-Shared-Attac
headerTitle: () => (
<CustomText numberOfLines={1}>
<Trans
i18nKey='screenTabs:shared.attachments.name'
ns='screenTabs'
i18nKey='shared.attachments.name'
components={[
<ParseEmojis
content={account.display_name || account.username}

View File

@ -27,7 +27,7 @@ const TabSharedHashtag: React.FC<TabSharedStackScreenProps<'Tab-Shared-Hashtag'>
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Hashtag', hashtag }]
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const canFollowTags = useSelector(checkInstanceFeature('follow_tags'))
const { data, isFetching, refetch } = useTagsQuery({
@ -46,7 +46,9 @@ const TabSharedHashtag: React.FC<TabSharedStackScreenProps<'Tab-Shared-Hashtag'>
displayMessage({
type: 'error',
message: t('common:message.error.message', {
function: to ? t('shared.hashtag.follow') : t('shared.hashtag.unfollow')
function: to
? t('screenTabs:shared.hashtag.follow')
: t('screenTabs:shared.hashtag.unfollow')
}),
...(err.status &&
typeof err.status === 'number' &&
@ -66,7 +68,11 @@ const TabSharedHashtag: React.FC<TabSharedStackScreenProps<'Tab-Shared-Hashtag'>
<HeaderRight
loading={isFetching || mutation.isLoading}
type='text'
content={data?.following ? t('shared.hashtag.unfollow') : t('shared.hashtag.follow')}
content={
data?.following
? t('screenTabs:shared.hashtag.unfollow')
: t('screenTabs:shared.hashtag.follow')
}
onPress={() =>
typeof data?.following === 'boolean' &&
mutation.mutate({ tag: hashtag, to: !data.following })

View File

@ -21,14 +21,14 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
}
}) => {
const { colors } = useTheme()
const { t } = useTranslation('screenTabs')
const { t } = useTranslation(['common', 'screenTabs'])
const [categories, setCategories] = useState<
{ selected: boolean; content: string; type: 'spam' | 'other' | 'violation' }[]
>([
{ selected: true, content: t('shared.report.reasons.spam'), type: 'spam' },
{ selected: false, content: t('shared.report.reasons.other'), type: 'other' },
{ selected: false, content: t('shared.report.reasons.violation'), type: 'violation' }
{ selected: true, content: t('screenTabs:shared.report.reasons.spam'), type: 'spam' },
{ selected: false, content: t('screenTabs:shared.report.reasons.other'), type: 'other' },
{ selected: false, content: t('screenTabs:shared.report.reasons.violation'), type: 'violation' }
])
const [rules, setRules] = useState<{ selected: boolean; content: string; id: string }[]>([])
const [forward, setForward] = useState<boolean>(true)
@ -37,7 +37,7 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
const [isReporting, setIsReporting] = useState(false)
useEffect(() => {
navigation.setOptions({
title: t('shared.report.name', { acct: `@${account.acct}` }),
title: t('screenTabs:shared.report.name', { acct: `@${account.acct}` }),
headerLeft: () => (
<HeaderLeft
type='text'
@ -48,7 +48,7 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
headerRight: () => (
<HeaderRight
type='text'
content={t('shared.report.report')}
content={t('screenTabs:shared.report.report')}
destructive
onPress={() => {
const body = new FormData()
@ -119,7 +119,9 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
style={{ color: colors.primaryDefault, paddingRight: StyleConstants.Spacing.M }}
numberOfLines={2}
>
{t('shared.report.forward.heading', { instance: account.acct.match(/@(.*)/)?.[1] })}
{t('screenTabs:shared.report.forward.heading', {
instance: account.acct.match(/@(.*)/)?.[1]
})}
</CustomText>
<Switch
value={forward}
@ -133,7 +135,7 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
fontStyle='M'
style={{ color: colors.primaryDefault, marginBottom: StyleConstants.Spacing.S }}
>
{t('shared.report.reasons.heading')}
{t('screenTabs:shared.report.reasons.heading')}
</CustomText>
<View style={{ marginLeft: StyleConstants.Spacing.M }}>
<Selections options={categories} setOptions={setCategories} />
@ -149,7 +151,7 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
marginBottom: StyleConstants.Spacing.XS
}}
>
{t('shared.report.comment.heading')}
{t('screenTabs:shared.report.comment.heading')}
</CustomText>
<View
style={{
@ -198,7 +200,7 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
marginBottom: StyleConstants.Spacing.S
}}
>
{t('shared.report.violatedRules.heading')}
{t('screenTabs:shared.report.violatedRules.heading')}
</CustomText>
<View style={{ marginLeft: StyleConstants.Spacing.M }}>
<Selections

View File

@ -38,7 +38,8 @@ const SearchEmpty: React.FC<Props> = ({ isFetching, inputRef, setSearchTerm }) =
}}
>
<Trans
i18nKey='screenTabs:shared.search.empty.general'
ns='screenTabs'
i18nKey='shared.search.empty.general'
components={{
bold: <CustomText fontWeight='Bold' />
}}

View File

@ -179,7 +179,8 @@ const TabSharedSearch: React.FC<TabSharedStackScreenProps<'Tab-Shared-Search'>>
>
<CustomText fontStyle='S' style={{ textAlign: 'center', color: colors.secondary }}>
<Trans
i18nKey='screenTabs:shared.search.notFound'
ns='screenTabs'
i18nKey='shared.search.notFound'
values={{ searchTerm, type: translation }}
components={{
bold: <CustomText fontWeight='Bold' />

View File

@ -23,7 +23,9 @@ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> =
const { t } = useTranslation('screenTabs')
useEffect(() => {
navigation.setOptions({
title: t(`shared.users.${params.reference}.${params.type}`, { count: params.count }),
title: t(`shared.users.${params.reference}.${params.type}`, {
count: params.count
} as any) as any,
headerLeft: () => <HeaderLeft onPress={() => navigation.goBack()} />
})
}, [])

View File

@ -1,5 +1,5 @@
import * as Sentry from "@sentry/react-native";
import { isDevelopment } from "@utils/checkEnvironment";
import * as Sentry from '@sentry/react-native'
import { isDevelopment } from '@utils/checkEnvironment'
import log from './log'
const sentry = () => {
@ -10,8 +10,8 @@ const sentry = () => {
tracesSampleRate: 0.35,
integrations: [
new Sentry.ReactNativeTracing({
tracingOrigins: ["tooot.app"],
}),
tracingOrigins: ['api.tooot.app']
})
],
autoSessionTracking: true
})

View File

@ -129,7 +129,7 @@ const useProfileMutation = () => {
displayMessage({
ref: variables.messageRef,
message: i18next.t('screenTabs:me.profile.feedback.failed', {
type: i18next.t(`screenTabs:${variables.message.text}`)
type: i18next.t(`screenTabs:${variables.message.text}` as any)
}),
...(err && { description: err.message }),
type: 'danger'
@ -142,7 +142,7 @@ const useProfileMutation = () => {
displayMessage({
ref: variables.messageRef,
message: i18next.t('screenTabs:me.profile.feedback.succeed', {
type: i18next.t(`screenTabs:${variables.message.text}`)
type: i18next.t(`screenTabs:${variables.message.text}` as any)
}),
type: 'success'
})

View File

@ -70,7 +70,7 @@ export const setChannels = async (instance: InstanceLatest, reset: boolean | und
const setChannel = async (type: string) =>
Notifications.setNotificationChannelAsync(`${account}_${type}`, {
groupId: account,
name: i18n.t(`screenTabs:me.push.${type}.heading`),
name: i18n.t(`screenTabs:me.push.${type}.heading` as any),
importance: Notifications.AndroidImportance.DEFAULT,
bypassDnd: false,
showBadge: true,

952
yarn.lock

File diff suppressed because it is too large Load Diff