Added pt-BR

https://github.com/tooot-app/app/issues/302
This commit is contained in:
Zhiyuan Zheng 2022-05-28 22:18:03 +02:00
parent bdf7da120f
commit af6731f702
13 changed files with 181 additions and 135 deletions

View File

@ -6,10 +6,12 @@
## Special thanks
@forenta for German translation
[@forenta](https://github.com/forenta) for German translation
@andrigamerita for Italian translation
[@andrigamerita](https://github.com/andrigamerita) for Italian translation
@hellojaccc for Korean translation
[@hellojaccc](https://github.com/hellojaccc) for Korean translation
@duy@mas.to for Vietnamese translation
[@luizpicolo](https://github.com/luizpicolo) for Brazilian Portuguese
[@duy@mas.to](https://mas.to/@duy) for Vietnamese translation

View File

@ -4,7 +4,7 @@
"native": "220508",
"major": 4,
"minor": 0,
"patch": 3,
"patch": 4,
"expo": "45.0.0"
},
"description": "tooot app for Mastodon",

View File

@ -1,31 +1,4 @@
import { ActionSheetProvider } from '@expo/react-native-action-sheet'
import '@formatjs/intl-getcanonicallocales/polyfill'
import '@formatjs/intl-locale/polyfill'
import '@formatjs/intl-pluralrules/polyfill'
import '@formatjs/intl-pluralrules/locale-data/de'
import '@formatjs/intl-pluralrules/locale-data/en'
import '@formatjs/intl-pluralrules/locale-data/ko'
import '@formatjs/intl-pluralrules/locale-data/vi'
import '@formatjs/intl-pluralrules/locale-data/zh'
import '@formatjs/intl-numberformat/polyfill'
import '@formatjs/intl-numberformat/locale-data/de'
import '@formatjs/intl-numberformat/locale-data/en'
import '@formatjs/intl-numberformat/locale-data/ko'
import '@formatjs/intl-numberformat/locale-data/vi'
import '@formatjs/intl-numberformat/locale-data/zh'
import '@formatjs/intl-datetimeformat/polyfill'
import '@formatjs/intl-datetimeformat/locale-data/de'
import '@formatjs/intl-datetimeformat/locale-data/en'
import '@formatjs/intl-datetimeformat/locale-data/ko'
import '@formatjs/intl-datetimeformat/locale-data/vi'
import '@formatjs/intl-datetimeformat/locale-data/zh'
import '@formatjs/intl-datetimeformat/add-all-tz'
import '@formatjs/intl-relativetimeformat/polyfill'
import '@formatjs/intl-relativetimeformat/locale-data/de'
import '@formatjs/intl-relativetimeformat/locale-data/en'
import '@formatjs/intl-relativetimeformat/locale-data/ko'
import '@formatjs/intl-relativetimeformat/locale-data/vi'
import '@formatjs/intl-relativetimeformat/locale-data/zh'
import queryClient from '@helpers/queryClient'
import i18n from '@root/i18n/i18n'
import Screens from '@root/Screens'

View File

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

View File

@ -43,6 +43,9 @@
"fontSize": {
"name": "Toot Font Size"
},
"language": {
"name": "Language"
},
"lists": {
"name": "Lists"
},
@ -221,7 +224,7 @@
}
},
"language": {
"heading": "Language",
"heading": "$t(me.stacks.language.name)",
"options": {
"cancel": "$t(common:buttons.cancel)"
}

View File

@ -5,9 +5,42 @@ import de from '@root/i18n/de/_all'
import en from '@root/i18n/en/_all'
import it from '@root/i18n/it/_all'
import ko from '@root/i18n/ko/_all'
import pt_BR from '@root/i18n/pt_BR/_all'
import vi from '@root/i18n/vi/_all'
import zh_Hans from '@root/i18n/zh-Hans/_all'
import '@formatjs/intl-getcanonicallocales/polyfill'
import '@formatjs/intl-locale/polyfill'
import '@formatjs/intl-pluralrules/polyfill'
import '@formatjs/intl-pluralrules/locale-data/de'
import '@formatjs/intl-pluralrules/locale-data/en'
import '@formatjs/intl-pluralrules/locale-data/ko'
import '@formatjs/intl-pluralrules/locale-data/pt'
import '@formatjs/intl-pluralrules/locale-data/vi'
import '@formatjs/intl-pluralrules/locale-data/zh'
import '@formatjs/intl-numberformat/polyfill'
import '@formatjs/intl-numberformat/locale-data/de'
import '@formatjs/intl-numberformat/locale-data/en'
import '@formatjs/intl-numberformat/locale-data/ko'
import '@formatjs/intl-numberformat/locale-data/pt'
import '@formatjs/intl-numberformat/locale-data/vi'
import '@formatjs/intl-numberformat/locale-data/zh-Hans'
import '@formatjs/intl-datetimeformat/polyfill'
import '@formatjs/intl-datetimeformat/locale-data/de'
import '@formatjs/intl-datetimeformat/locale-data/en'
import '@formatjs/intl-datetimeformat/locale-data/ko'
import '@formatjs/intl-datetimeformat/locale-data/pt'
import '@formatjs/intl-datetimeformat/locale-data/vi'
import '@formatjs/intl-datetimeformat/locale-data/zh-Hans'
import '@formatjs/intl-datetimeformat/add-all-tz'
import '@formatjs/intl-relativetimeformat/polyfill'
import '@formatjs/intl-relativetimeformat/locale-data/de'
import '@formatjs/intl-relativetimeformat/locale-data/en'
import '@formatjs/intl-relativetimeformat/locale-data/ko'
import '@formatjs/intl-relativetimeformat/locale-data/pt'
import '@formatjs/intl-relativetimeformat/locale-data/vi'
import '@formatjs/intl-relativetimeformat/locale-data/zh-Hans'
i18n.use(initReactI18next).init({
lng: 'en',
fallbackLng: 'en',
@ -15,7 +48,7 @@ i18n.use(initReactI18next).init({
ns: ['common'],
defaultNS: 'common',
resources: { 'zh-Hans': zh_Hans, vi, ko, it, en, de },
resources: { 'zh-Hans': zh_Hans, vi, 'pt-BR': pt_BR, ko, it, en, de },
returnEmptyString: false,
saveMissing: true,

View File

@ -3,6 +3,7 @@ const LOCALES = {
en: 'English',
it: 'Italiano',
ko: '한국어',
'pt-BR': 'Português (Brasil)',
vi: 'Tiếng Việt',
'zh-Hans': '简体中文'
}

17
src/i18n/pt_BR/_all.ts Normal file
View File

@ -0,0 +1,17 @@
export default {
common: require('./common'),
screens: require('./screens'),
screenActions: require('./screens/actions'),
screenAnnouncements: require('./screens/announcements'),
screenCompose: require('./screens/compose'),
screenImageViewer: require('./screens/imageViewer'),
screenTabs: require('./screens/tabs'),
componentEmojis: require('./components/emojis'),
componentInstance: require('./components/instance'),
componentMediaSelector: require('./components/mediaSelector'),
componentParse: require('./components/parse'),
componentRelationship: require('./components/relationship'),
componentTimeline: require('./components/timeline')
}

View File

@ -14,6 +14,7 @@ import TabMePush from './Me/Push'
import TabMeRoot from './Me/Root'
import TabMeSettings from './Me/Settings'
import TabMeSettingsFontsize from './Me/SettingsFontsize'
import TabMeSettingsLanguage from './Me/SettingsLanguage'
import TabMeSwitch from './Me/Switch'
import TabSharedRoot from './Shared/Root'
@ -152,6 +153,19 @@ const TabMe = React.memo(
headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} />
})}
/>
<Stack.Screen
name='Tab-Me-Settings-Language'
component={TabMeSettingsLanguage}
options={({ navigation }: any) => ({
title: t('me.stacks.language.name'),
...(Platform.OS === 'android' && {
headerCenter: () => (
<HeaderCenter content={t('me.stacks.language.name')} />
)
}),
headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} />
})}
/>
<Stack.Screen
name='Tab-Me-Switch'
component={TabMeSwitch}

View File

@ -5,11 +5,8 @@ import { useActionSheet } from '@expo/react-native-action-sheet'
import { useNavigation } from '@react-navigation/native'
import { LOCALES } from '@root/i18n/locales'
import { useAppDispatch } from '@root/store'
import androidDefaults from '@utils/slices/instances/push/androidDefaults'
import { getInstances } from '@utils/slices/instancesSlice'
import {
changeBrowser,
changeLanguage,
changeTheme,
getSettingsTheme,
getSettingsBrowser,
@ -19,11 +16,8 @@ import {
getSettingsStaticEmoji,
changeStaticEmoji
} from '@utils/slices/settingsSlice'
import { useTheme } from '@utils/styles/ThemeManager'
import * as Notifications from 'expo-notifications'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Platform } from 'react-native'
import { useSelector } from 'react-redux'
import { mapFontsizeToName } from '../SettingsFontsize'
@ -31,10 +25,8 @@ const SettingsApp: React.FC = () => {
const navigation = useNavigation<any>()
const dispatch = useAppDispatch()
const { showActionSheetWithOptions } = useActionSheet()
const { mode } = useTheme()
const { t, i18n } = useTranslation('screenTabs')
const instances = useSelector(getInstances, () => true)
const settingsFontsize = useSelector(getSettingsFontsize)
const settingsTheme = useSelector(getSettingsTheme)
const settingsDarkTheme = useSelector(getSettingsDarkTheme)
@ -49,102 +41,14 @@ const SettingsApp: React.FC = () => {
`me.settings.fontsize.content.${mapFontsizeToName(settingsFontsize)}`
)}
iconBack='ChevronRight'
onPress={() => {
navigation.navigate('Tab-Me-Settings-Fontsize')
}}
onPress={() => navigation.navigate('Tab-Me-Settings-Fontsize')}
/>
<MenuRow
title={t('me.settings.language.heading')}
// @ts-ignore
content={LOCALES[i18n.language]}
iconBack='ChevronRight'
onPress={() => {
const options = Object.keys(LOCALES)
// @ts-ignore
.map(locale => LOCALES[locale])
.concat(t('me.settings.language.options.cancel'))
showActionSheetWithOptions(
{
title: t('me.settings.language.heading'),
options,
cancelButtonIndex: options.length - 1,
userInterfaceStyle: mode
},
buttonIndex => {
if (buttonIndex === undefined) return
if (buttonIndex < options.length - 1) {
analytics('settings_language_press', {
current: i18n.language,
new: options[buttonIndex]
})
haptics('Success')
// @ts-ignore
dispatch(changeLanguage(Object.keys(LOCALES)[buttonIndex]))
i18n.changeLanguage(Object.keys(LOCALES)[buttonIndex])
// Update Android notification channel language
if (Platform.OS === 'android') {
instances.forEach(instance => {
const accountFull = `@${instance.account.acct}@${instance.uri}`
if (instance.push.decode.value === false) {
Notifications.setNotificationChannelAsync(
`${accountFull}_default`,
{
groupId: accountFull,
name: t('me.push.default.heading'),
...androidDefaults
}
)
} else {
Notifications.setNotificationChannelAsync(
`${accountFull}_follow`,
{
groupId: accountFull,
name: t('me.push.follow.heading'),
...androidDefaults
}
)
Notifications.setNotificationChannelAsync(
`${accountFull}_favourite`,
{
groupId: accountFull,
name: t('me.push.favourite.heading'),
...androidDefaults
}
)
Notifications.setNotificationChannelAsync(
`${accountFull}_reblog`,
{
groupId: accountFull,
name: t('me.push.reblog.heading'),
...androidDefaults
}
)
Notifications.setNotificationChannelAsync(
`${accountFull}_mention`,
{
groupId: accountFull,
name: t('me.push.mention.heading'),
...androidDefaults
}
)
Notifications.setNotificationChannelAsync(
`${accountFull}_poll`,
{
groupId: accountFull,
name: t('me.push.poll.heading'),
...androidDefaults
}
)
}
})
}
}
}
)
}}
onPress={() => navigation.navigate('Tab-Me-Settings-Language')}
/>
<MenuRow
title={t('me.settings.theme.heading')}

View File

@ -45,7 +45,7 @@ const TabMeSettingsFontsize: React.FC<
const item = {
id: 'demo',
uri: 'https://tooot.app',
created_at: new Date(),
created_at: new Date(2021, 4, 16),
sensitive: false,
visibility: 'public',
replies_count: 0,
@ -67,6 +67,7 @@ const TabMeSettingsFontsize: React.FC<
username: 'tooot📱',
acct: 'tooot@xmflsct.com',
display_name: 'tooot📱',
avatar: 'https://avatars.githubusercontent.com/u/77554750?s=100',
avatar_static: 'https://avatars.githubusercontent.com/u/77554750?s=100'
},
media_attachments: [],
@ -100,7 +101,7 @@ const TabMeSettingsFontsize: React.FC<
}, [theme, initialSize])
return (
<ScrollView scrollEnabled={false}>
<ScrollView>
<CustomText
fontStyle='M'
style={{

View File

@ -0,0 +1,97 @@
import analytics from '@components/analytics'
import haptics from '@components/haptics'
import { MenuContainer, MenuRow } from '@components/Menu'
import { LOCALES } from '@root/i18n/locales'
import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import androidDefaults from '@utils/slices/instances/push/androidDefaults'
import { getInstances } from '@utils/slices/instancesSlice'
import { changeLanguage } from '@utils/slices/settingsSlice'
import * as Notifications from 'expo-notifications'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { FlatList, Platform } from 'react-native'
import { useDispatch, useSelector } from 'react-redux'
const TabMeSettingsLanguage: React.FC<
TabMeStackScreenProps<'Tab-Me-Settings-Language'>
> = () => {
const { i18n, t } = useTranslation('screenTabs')
const languages = Object.entries(LOCALES)
const instances = useSelector(getInstances)
const dispatch = useDispatch()
const change = (lang: string) => {
analytics('settings_language_press', {
current: i18n.language,
new: lang
})
haptics('Success')
dispatch(changeLanguage(lang))
i18n.changeLanguage(lang)
// Update Android notification channel language
if (Platform.OS === 'android') {
instances.forEach(instance => {
const accountFull = `@${instance.account.acct}@${instance.uri}`
if (instance.push.decode.value === false) {
Notifications.setNotificationChannelAsync(`${accountFull}_default`, {
groupId: accountFull,
name: t('me.push.default.heading'),
...androidDefaults
})
} else {
Notifications.setNotificationChannelAsync(`${accountFull}_follow`, {
groupId: accountFull,
name: t('me.push.follow.heading'),
...androidDefaults
})
Notifications.setNotificationChannelAsync(
`${accountFull}_favourite`,
{
groupId: accountFull,
name: t('me.push.favourite.heading'),
...androidDefaults
}
)
Notifications.setNotificationChannelAsync(`${accountFull}_reblog`, {
groupId: accountFull,
name: t('me.push.reblog.heading'),
...androidDefaults
})
Notifications.setNotificationChannelAsync(`${accountFull}_mention`, {
groupId: accountFull,
name: t('me.push.mention.heading'),
...androidDefaults
})
Notifications.setNotificationChannelAsync(`${accountFull}_poll`, {
groupId: accountFull,
name: t('me.push.poll.heading'),
...androidDefaults
})
}
})
}
}
return (
<MenuContainer>
<FlatList
data={languages}
renderItem={({ item }) => {
return (
<MenuRow
key={item[0]}
title={item[1]}
iconBack={item[0] === i18n.language ? 'Check' : undefined}
iconBackColor={'blue'}
onPress={() => item[0] !== i18n.language && change(item[0])}
/>
)
}}
/>
</MenuContainer>
)
}
export default TabMeSettingsLanguage

View File

@ -146,6 +146,7 @@ export type TabMeStackParamList = {
'Tab-Me-Push': undefined
'Tab-Me-Settings': undefined
'Tab-Me-Settings-Fontsize': undefined
'Tab-Me-Settings-Language': undefined
'Tab-Me-Switch': undefined
} & TabSharedStackParamList
export type TabMeStackScreenProps<T extends keyof TabMeStackParamList> =