Some translations are done

This commit is contained in:
Zhiyuan Zheng 2020-11-30 00:24:53 +01:00
parent 1493e20962
commit 0e3528d2cd
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
42 changed files with 428 additions and 176 deletions

View File

@ -17,6 +17,7 @@ import { themes } from 'src/utils/styles/themes'
import { useTheme } from 'src/utils/styles/ThemeManager'
import getCurrentTab from 'src/utils/getCurrentTab'
import { toastConfig } from 'src/components/toast'
import { useTranslation } from 'react-i18next'
enableScreens()
const Tab = createBottomTabNavigator<RootStackParamList>()
@ -30,6 +31,7 @@ export type RootStackParamList = {
}
export const Index: React.FC = () => {
const { i18n } = useTranslation()
const { mode, theme } = useTheme()
enum barStyle {
light = 'dark-content',
@ -39,7 +41,7 @@ export const Index: React.FC = () => {
return (
<>
<StatusBar barStyle={barStyle[mode]} />
<NavigationContainer theme={themes[mode]}>
<NavigationContainer theme={themes[mode]} key={i18n.language}>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {

View File

@ -11,8 +11,7 @@ import {
} from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
children: React.ReactNode
@ -104,23 +103,23 @@ const styles = StyleSheet.create({
justifyContent: 'flex-end'
},
container: {
padding: constants.SPACING_L,
paddingTop: constants.SPACING_M
padding: StyleConstants.Spacing.L,
paddingTop: StyleConstants.Spacing.M
},
handle: {
alignSelf: 'center',
width: constants.GLOBAL_SPACING_BASE * 8,
height: constants.GLOBAL_SPACING_BASE / 2,
width: StyleConstants.Spacing.Global.PagePadding * 8,
height: StyleConstants.Spacing.Global.PagePadding / 2,
borderRadius: 100,
top: -constants.SPACING_M * 2
top: -StyleConstants.Spacing.M * 2
},
cancel: {
padding: constants.SPACING_S,
padding: StyleConstants.Spacing.S,
borderWidth: 1,
borderRadius: 100
},
text: {
fontSize: constants.FONT_SIZE_L,
fontSize: StyleConstants.Font.Size.L,
textAlign: 'center'
}
})

View File

@ -2,8 +2,8 @@ import React from 'react'
import { Pressable, StyleSheet, Text } from 'react-native'
import { Feather } from '@expo/vector-icons'
import constants from 'src/utils/styles/constants'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
onPressFunction: () => void
@ -16,7 +16,11 @@ const BottomSheetRow: React.FC<Props> = ({ onPressFunction, icon, text }) => {
return (
<Pressable onPress={() => onPressFunction()} style={styles.pressable}>
<Feather name={icon} color={theme.primary} size={constants.FONT_SIZE_L} />
<Feather
name={icon}
color={theme.primary}
size={StyleConstants.Font.Size.L}
/>
<Text style={[styles.text, { color: theme.primary }]}>{text}</Text>
</Pressable>
)
@ -25,12 +29,12 @@ const BottomSheetRow: React.FC<Props> = ({ onPressFunction, icon, text }) => {
const styles = StyleSheet.create({
pressable: {
flexDirection: 'row',
marginBottom: constants.SPACING_L
marginBottom: StyleConstants.Spacing.L
},
text: {
fontSize: constants.FONT_SIZE_M,
lineHeight: constants.FONT_SIZE_L,
marginLeft: constants.SPACING_S
fontSize: StyleConstants.Font.Size.M,
lineHeight: StyleConstants.Font.Size.L,
marginLeft: StyleConstants.Spacing.S
}
})

View File

@ -0,0 +1,4 @@
import HeaderLeft from './Header/Left'
import HeaderRight from './Header/Right'
export { HeaderLeft, HeaderRight }

View File

@ -0,0 +1,41 @@
import { Feather } from '@expo/vector-icons'
import React from 'react'
import { Pressable, StyleSheet, Text } from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
onPress: () => void
text?: string
icon?: string
}
const HeaderLeft: React.FC<Props> = ({ onPress, text, icon }) => {
const { theme } = useTheme()
return (
<Pressable onPress={onPress} style={styles.base}>
{text ? (
<Text style={[styles.text, { color: theme.link }]}>{text}</Text>
) : (
<Feather
name={icon || 'chevron-left'}
color={theme.link}
size={StyleConstants.Font.Size.L}
/>
)}
</Pressable>
)
}
const styles = StyleSheet.create({
base: {
paddingRight: StyleConstants.Spacing.S
},
text: {
fontSize: StyleConstants.Font.Size.L
}
})
export default HeaderLeft

View File

@ -0,0 +1,52 @@
import { Feather } from '@expo/vector-icons'
import React from 'react'
import { Pressable, StyleSheet, Text } from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { StyleConstants } from 'src/utils/styles/constants'
type PropsBase = {
onPress: () => void
}
export interface PropsText extends PropsBase {
text: string
icon?: string
}
export interface PropsIcon extends PropsBase {
text?: string
icon: string
}
const HeaderRight: React.FC<PropsText | PropsIcon> = ({
onPress,
text,
icon
}) => {
const { theme } = useTheme()
return (
<Pressable onPress={onPress} style={styles.base}>
{text && <Text style={[styles.text, { color: theme.link }]}>{text}</Text>}
{icon && (
<Feather
name={icon}
color={theme.link}
size={StyleConstants.Font.Size.L}
/>
)}
</Pressable>
)
}
const styles = StyleSheet.create({
base: {
paddingLeft: StyleConstants.Spacing.S
},
text: {
fontSize: StyleConstants.Font.Size.L
}
})
export default HeaderRight

View File

@ -9,8 +9,7 @@ import {
View
} from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
text: string
@ -66,8 +65,8 @@ const styles = StyleSheet.create({
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: constants.GLOBAL_PAGE_PADDING,
paddingRight: constants.GLOBAL_PAGE_PADDING
paddingLeft: StyleConstants.Spacing.Global.PagePadding,
paddingRight: StyleConstants.Spacing.Global.PagePadding
}
})

View File

@ -1,8 +1,7 @@
import React from 'react'
import { StyleSheet, View } from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
children: React.ReactNode
@ -18,7 +17,9 @@ const MenuContainer: React.FC<Props> = ({ ...props }) => {
styles.base,
{
borderTopColor: theme.separator,
marginTop: props.marginTop ? constants.GLOBAL_PAGE_PADDING : 0
marginTop: props.marginTop
? StyleConstants.Spacing.Global.PagePadding
: 0
}
]}
>
@ -30,7 +31,7 @@ const MenuContainer: React.FC<Props> = ({ ...props }) => {
const styles = StyleSheet.create({
base: {
borderTopWidth: 1,
marginBottom: constants.GLOBAL_PAGE_PADDING
marginBottom: StyleConstants.Spacing.Global.PagePadding
}
})

View File

@ -3,8 +3,8 @@ import { Pressable, StyleSheet, Text, View } from 'react-native'
import { Feather } from '@expo/vector-icons'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { ColorDefinitions } from 'src/utils/styles/themes'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
iconFront?: string
@ -34,7 +34,7 @@ const Core: React.FC<Props> = ({
{iconFront && (
<Feather
name={iconFront}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
color={theme[iconFrontColor]}
style={styles.iconFront}
/>
@ -55,7 +55,7 @@ const Core: React.FC<Props> = ({
{iconBack && (
<Feather
name={iconBack}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
color={theme[iconBackColor]}
style={styles.iconBack}
/>
@ -90,8 +90,8 @@ const styles = StyleSheet.create({
core: {
flex: 1,
flexDirection: 'row',
paddingLeft: constants.GLOBAL_PAGE_PADDING,
paddingRight: constants.GLOBAL_PAGE_PADDING
paddingLeft: StyleConstants.Spacing.Global.PagePadding,
paddingRight: StyleConstants.Spacing.Global.PagePadding
},
front: {
flex: 1,
@ -108,10 +108,10 @@ const styles = StyleSheet.create({
marginRight: 8
},
text: {
fontSize: constants.FONT_SIZE_M
fontSize: StyleConstants.Font.Size.M
},
content: {
fontSize: constants.FONT_SIZE_M
fontSize: StyleConstants.Font.Size.M
},
iconBack: {
marginLeft: 8

View File

@ -0,0 +1,3 @@
import NetworkStateError from './NetworkState/Error'
export { NetworkStateError }

View File

@ -0,0 +1,20 @@
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
const NetworkStateError = () => {
return (
<View style={styles.base}>
<Text></Text>
</View>
)
}
const styles = StyleSheet.create({
base: {
flex: 1,
// justifyContent: 'center',
alignItems: 'center'
}
})
export default NetworkStateError

View File

@ -5,8 +5,7 @@ import { useNavigation } from '@react-navigation/native'
import Avatar from './Shared/Avatar'
import HeaderConversation from './Shared/HeaderConversation'
import Content from './Shared/Content'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
item: Mastodon.Conversation
@ -60,7 +59,7 @@ const styles = StyleSheet.create({
statusView: {
flex: 1,
flexDirection: 'column',
padding: constants.GLOBAL_PAGE_PADDING
padding: StyleConstants.Spacing.Global.PagePadding
},
status: {
flex: 1,

View File

@ -10,8 +10,7 @@ import Poll from './Shared/Poll'
import Attachment from './Shared/Attachment'
import Card from './Shared/Card'
import ActionsStatus from './Shared/ActionsStatus'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
item: Mastodon.Status
@ -51,7 +50,7 @@ const TimelineDefault: React.FC<Props> = ({ item, queryKey }) => {
media_attachments={actualStatus.media_attachments}
sensitive={actualStatus.sensitive}
width={
Dimensions.get('window').width - constants.SPACING_M * 2 - 50 - 8
Dimensions.get('window').width - StyleConstants.Spacing.M * 2 - 50 - 8
}
/>
)}
@ -107,7 +106,7 @@ const styles = StyleSheet.create({
statusView: {
flex: 1,
flexDirection: 'column',
padding: constants.GLOBAL_PAGE_PADDING
padding: StyleConstants.Spacing.Global.PagePadding
},
status: {
flex: 1,

View File

@ -10,8 +10,7 @@ import Poll from './Shared/Poll'
import Attachment from './Shared/Attachment'
import Card from './Shared/Card'
import ActionsStatus from './Shared/ActionsStatus'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
notification: Mastodon.Notification
@ -98,7 +97,7 @@ const styles = StyleSheet.create({
notificationView: {
flex: 1,
flexDirection: 'column',
padding: constants.GLOBAL_PAGE_PADDING
padding: StyleConstants.Spacing.Global.PagePadding
},
notification: {
flex: 1,

View File

@ -1,8 +1,8 @@
import React from 'react'
import { StyleSheet, View } from 'react-native'
import constants from 'src/utils/styles/constants'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { StyleConstants } from 'src/utils/styles/constants'
const TimelineSeparator = () => {
const { theme } = useTheme()
@ -13,8 +13,11 @@ const TimelineSeparator = () => {
const styles = StyleSheet.create({
base: {
borderTopWidth: 1,
marginLeft: constants.SPACING_M + constants.AVATAR_S + constants.SPACING_S,
marginRight: constants.SPACING_M
marginLeft:
StyleConstants.Spacing.M +
StyleConstants.Avatar.S +
StyleConstants.Spacing.S,
marginRight: StyleConstants.Spacing.M
}
})

View File

@ -4,8 +4,7 @@ import { Feather } from '@expo/vector-icons'
import Emojis from './Emojis'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
action: 'favourite' | 'follow' | 'mention' | 'poll' | 'reblog'
@ -30,7 +29,7 @@ const Actioned: React.FC<Props> = ({
icon = (
<Feather
name='heart'
size={constants.FONT_SIZE_S}
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
/>
@ -41,7 +40,7 @@ const Actioned: React.FC<Props> = ({
icon = (
<Feather
name='user-plus'
size={constants.FONT_SIZE_S}
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
/>
@ -52,7 +51,7 @@ const Actioned: React.FC<Props> = ({
icon = (
<Feather
name='bar-chart-2'
size={constants.FONT_SIZE_S}
size={StyleConstants.Font.Size.S}
color='black'
style={styles.icon}
/>
@ -63,7 +62,7 @@ const Actioned: React.FC<Props> = ({
icon = (
<Feather
name='repeat'
size={constants.FONT_SIZE_S}
size={StyleConstants.Font.Size.S}
color={iconColor}
style={styles.icon}
/>
@ -81,7 +80,7 @@ const Actioned: React.FC<Props> = ({
<Emojis
content={content}
emojis={emojis}
size={constants.FONT_SIZE_S}
size={StyleConstants.Font.Size.S}
/>
) : (
<Text>{content}</Text>
@ -97,11 +96,11 @@ const Actioned: React.FC<Props> = ({
const styles = StyleSheet.create({
actioned: {
flexDirection: 'row',
marginBottom: constants.SPACING_S
marginBottom: StyleConstants.Spacing.S
},
icon: {
marginLeft: constants.AVATAR_S - constants.FONT_SIZE_S,
marginRight: constants.SPACING_S
marginLeft: StyleConstants.Avatar.S - StyleConstants.Font.Size.S,
marginRight: StyleConstants.Spacing.S
},
content: {
flexDirection: 'row'

View File

@ -14,9 +14,9 @@ import { Feather } from '@expo/vector-icons'
import client from 'src/api/client'
import { getLocalAccountId } from 'src/utils/slices/instancesSlice'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { toast } from 'src/components/toast'
import { useSelector } from 'react-redux'
import { StyleConstants } from 'src/utils/styles/constants'
const fireMutation = async ({
id,
@ -175,14 +175,14 @@ const ActionsStatus: React.FC<Props> = ({ queryKey, status }) => {
<Feather
name='message-circle'
color={iconColor}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
{status.replies_count > 0 && (
<Text
style={{
color: theme.secondary,
fontSize: constants.FONT_SIZE_M,
marginLeft: constants.SPACING_XS
fontSize: StyleConstants.Font.Size.M,
marginLeft: StyleConstants.Spacing.XS
}}
>
{status.replies_count}
@ -201,7 +201,7 @@ const ActionsStatus: React.FC<Props> = ({ queryKey, status }) => {
? iconColorAction(status.reblogged)
: theme.disabled
}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
),
[status.reblogged]
@ -211,7 +211,7 @@ const ActionsStatus: React.FC<Props> = ({ queryKey, status }) => {
<Feather
name='heart'
color={iconColorAction(status.favourited)}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
),
[status.favourited]
@ -221,7 +221,7 @@ const ActionsStatus: React.FC<Props> = ({ queryKey, status }) => {
<Feather
name='bookmark'
color={iconColorAction(status.bookmarked)}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
),
[status.bookmarked]
@ -231,7 +231,7 @@ const ActionsStatus: React.FC<Props> = ({ queryKey, status }) => {
<Feather
name='share-2'
color={iconColor}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
),
[]
@ -374,7 +374,7 @@ const styles = StyleSheet.create({
width: '100%',
flex: 1,
flexDirection: 'row',
marginTop: constants.SPACING_M
marginTop: StyleConstants.Spacing.M
},
action: {
width: '20%',

View File

@ -1,8 +1,7 @@
import React, { useCallback } from 'react'
import { Image, Pressable, StyleSheet } from 'react-native'
import { useNavigation } from '@react-navigation/native'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
uri: string
@ -27,9 +26,9 @@ const Avatar: React.FC<Props> = ({ uri, id }) => {
const styles = StyleSheet.create({
avatar: {
width: constants.AVATAR_S,
height: constants.AVATAR_S,
marginRight: constants.SPACING_S
width: StyleConstants.Avatar.S,
height: StyleConstants.Avatar.S,
marginRight: StyleConstants.Spacing.S
},
image: {
width: '100%',

View File

@ -4,8 +4,8 @@ import Collapsible from 'react-native-collapsible'
import ParseContent from 'src/components/ParseContent'
import constants from 'src/utils/styles/constants'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Props {
content: string
@ -40,7 +40,7 @@ const Content: React.FC<Props> = ({
<Collapsible collapsed={spoilerCollapsed}>
<ParseContent
content={content}
size={constants.FONT_SIZE_M}
size={StyleConstants.Font.Size.M}
emojis={emojis}
mentions={mentions}
/>
@ -49,7 +49,7 @@ const Content: React.FC<Props> = ({
) : (
<ParseContent
content={content}
size={constants.FONT_SIZE_M}
size={StyleConstants.Font.Size.M}
emojis={emojis}
mentions={mentions}
/>

View File

@ -1,8 +1,7 @@
import React from 'react'
import { Image, StyleSheet, Text } from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
const regexEmoji = new RegExp(/(:[a-z0-9_]+:)/)
@ -25,7 +24,7 @@ const Emojis: React.FC<Props> = ({
fontSize: size,
lineHeight: size + 2,
color: theme.primary,
...(fontBold && { fontWeight: constants.FONT_WEIGHT_BOLD })
...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold })
},
image: {
width: size,

View File

@ -9,11 +9,11 @@ import relativeTime from 'src/utils/relativeTime'
import client from 'src/api/client'
import { getLocalAccountId, getLocalUrl } from 'src/utils/slices/instancesSlice'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import BottomSheet from 'src/components/BottomSheet'
import BottomSheetRow from 'src/components/BottomSheet/Row'
import { toast } from 'src/components/toast'
import { useSelector } from 'react-redux'
import { StyleConstants } from 'src/utils/styles/constants'
const fireMutation = async ({
id,
@ -156,7 +156,7 @@ const HeaderDefault: React.FC<Props> = ({
<Feather
name='more-horizontal'
color={theme.secondary}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
),
[]
@ -170,7 +170,7 @@ const HeaderDefault: React.FC<Props> = ({
<Emojis
content={name}
emojis={emojis}
size={constants.FONT_SIZE_M}
size={StyleConstants.Font.Size.M}
fontBold={true}
/>
) : (
@ -202,7 +202,7 @@ const HeaderDefault: React.FC<Props> = ({
{visibility === 'private' && (
<Feather
name='lock'
size={constants.FONT_SIZE_S}
size={StyleConstants.Font.Size.S}
color={theme.secondary}
style={styles.visibility}
/>
@ -297,24 +297,24 @@ const styles = StyleSheet.create({
},
account: {
flexShrink: 1,
marginLeft: constants.SPACING_XS,
lineHeight: constants.FONT_SIZE_M + 2
marginLeft: StyleConstants.Spacing.XS,
lineHeight: StyleConstants.Font.Size.M + 2
},
meta: {
flexDirection: 'row',
alignItems: 'center',
marginTop: constants.SPACING_XS,
marginBottom: constants.SPACING_S
marginTop: StyleConstants.Spacing.XS,
marginBottom: StyleConstants.Spacing.S
},
created_at: {
fontSize: constants.FONT_SIZE_S
fontSize: StyleConstants.Font.Size.S
},
visibility: {
marginLeft: constants.SPACING_S
marginLeft: StyleConstants.Spacing.S
},
application: {
fontSize: constants.FONT_SIZE_S,
marginLeft: constants.SPACING_S
fontSize: StyleConstants.Font.Size.S,
marginLeft: StyleConstants.Spacing.S
}
})

View File

@ -3,8 +3,8 @@ import { StyleSheet, Text, View } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import Toast from 'react-native-toast-message'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { Feather } from '@expo/vector-icons'
import { StyleConstants } from 'src/utils/styles/constants'
export interface Params {
type: 'success' | 'error' | 'warning'
@ -65,7 +65,7 @@ const ToastBase = ({ config }: { config: Config }) => {
<Feather
name={iconSet[config.type]}
color={theme[config.type]}
size={constants.FONT_SIZE_M + 2}
size={StyleConstants.Font.Size.M + 2}
/>
<Text style={[styles.text, { color: theme.primary }]}>
{config.text1}
@ -91,11 +91,11 @@ const styles = StyleSheet.create({
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
padding: constants.SPACING_M
padding: StyleConstants.Spacing.M
},
text: {
fontSize: constants.FONT_SIZE_M,
marginLeft: constants.SPACING_S
fontSize: StyleConstants.Font.Size.M,
marginLeft: StyleConstants.Spacing.S
}
})

View File

@ -1,11 +1,21 @@
export default {
common: require('./common').default,
local: require('./screens/local').default,
public: require('./screens/public').default,
notifications: require('./screens/notifications').default,
meRoot: require('./screens/meRoot').default,
meConversations: require('./screens/meConversations').default,
meBookmarks: require('./screens/meBookmarks').default,
meFavourites: require('./screens/meFavourites').default,
meLists: require('./screens/meLists').default,
meListsList: require('./screens/meListsList').default,
meSettings: require('./screens/meSettings').default
meSettings: require('./screens/meSettings').default,
sharedAccount: require('./screens/sharedAccount').default,
sharedToot: require('./screens/sharedToot').default,
sharedWebview: require('./screens/sharedWebview').default
}

View File

@ -1,20 +1,5 @@
export default {
buttons: {
cancel: '取消'
},
headers: {
local: {
segments: {
left: '我的关注',
right: '本站嘟嘟'
}
},
public: {
segments: {
left: '跨站关注',
right: '外站嘟嘟'
}
},
notifications: '我的通知'
}
}

View File

@ -0,0 +1,9 @@
export default {
heading: {
segments: {
left: '我的关注',
right: '本站嘟嘟'
}
},
content: {}
}

View File

@ -1,7 +1,12 @@
export default {
heading: '我的长毛象',
content: {
login: {},
login: {
server: {
placeholder: '请输入服务器'
},
button: '登录'
},
collections: {
conversations: '$t(meConversations:heading)',
bookmarks: '$t(meBookmarks:heading)',

View File

@ -10,7 +10,7 @@ export default {
}
},
theme: {
heading: '颜色模式',
heading: '应用外观',
options: {
auto: '跟随系统',
light: '浅色模式',

View File

@ -0,0 +1,4 @@
export default {
heading: '通知',
content: {}
}

View File

@ -0,0 +1,9 @@
export default {
heading: {
segments: {
left: '跨站关注',
right: '外站嘟嘟'
}
},
content: {}
}

View File

@ -0,0 +1,19 @@
export default {
heading: {
loading: '加载中…',
error: '加载错误'
},
content: {
created_at: '加入时间:{{date}}',
summary: {
statuses_count: '{{count}} 条嘟文',
followers_count: '关注 {{count}} 人',
following_count: '被 {{count}} 人关注'
},
segments: {
left: '所有嘟嘟',
middle: '嘟嘟和回复',
right: '所有媒体'
}
}
}

View File

@ -0,0 +1,4 @@
export default {
heading: '对话',
content: {}
}

View File

@ -0,0 +1,7 @@
export default {
heading: {
loading: '加载中…',
error: '加载错误'
},
content: {}
}

View File

@ -10,8 +10,8 @@ const ScreenLocal: React.FC = () => {
<Timelines
name='Screen-Local-Root'
content={[
{ title: t('headers.local.segments.left'), page: 'Following' },
{ title: t('headers.local.segments.right'), page: 'Local' }
{ title: t('local:heading.segments.left'), page: 'Following' },
{ title: t('local:heading.segments.right'), page: 'Local' }
]}
/>
)

View File

@ -11,9 +11,11 @@ import { updateLocal } from 'src/utils/slices/instancesSlice'
import { useNavigation } from '@react-navigation/native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { useTranslation } from 'react-i18next'
import { StyleConstants } from 'src/utils/styles/constants'
const Login: React.FC = () => {
const { t } = useTranslation('meRoot')
const { theme } = useTheme()
const navigation = useNavigation()
const dispatch = useDispatch()
@ -126,7 +128,7 @@ const Login: React.FC = () => {
color: theme.primary,
borderColor: theme.border,
borderWidth: 1,
padding: constants.SPACING_M
padding: StyleConstants.Spacing.M
}}
onChangeText={onChangeText}
autoCapitalize='none'
@ -138,12 +140,12 @@ const Login: React.FC = () => {
onSubmitEditing={async () =>
isSuccess && data && data.uri && (await createApplication())
}
placeholder='输入服务器'
placeholder={t('content.login.server.placeholder')}
placeholderTextColor={theme.secondary}
returnKeyType='go'
/>
<Button
title='登录'
title={t('content.login.button')}
disabled={!data?.uri}
onPress={async () => await createApplication()}
/>
@ -158,7 +160,7 @@ const Login: React.FC = () => {
const styles = StyleSheet.create({
base: {
padding: constants.GLOBAL_PAGE_PADDING
padding: StyleConstants.Spacing.Global.PagePadding
}
})

View File

@ -18,7 +18,7 @@ const ScreenNotifications: React.FC = () => {
return (
<Stack.Navigator
screenOptions={{ headerTitle: t('headers.notifications') }}
screenOptions={{ headerTitle: t('notifications:heading') }}
>
<Stack.Screen name='Screen-Notifications-Root'>
{() =>

View File

@ -10,8 +10,8 @@ const ScreenPublic: React.FC = () => {
<Timelines
name='Screen-Public-Root'
content={[
{ title: t('headers.public.segments.left'), page: 'LocalPublic' },
{ title: t('headers.public.segments.right'), page: 'RemotePublic' }
{ title: t('public:heading.segments.left'), page: 'LocalPublic' },
{ title: t('public:heading.segments.right'), page: 'RemotePublic' }
]}
/>
)

View File

@ -5,14 +5,15 @@ import { Feather } from '@expo/vector-icons'
import ParseContent from 'src/components/ParseContent'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
import { StyleConstants } from 'src/utils/styles/constants'
import { useTranslation } from 'react-i18next'
export interface Props {
account: Mastodon.Account | undefined
}
const AccountInformation: React.FC<Props> = ({ account }) => {
const { t } = useTranslation('sharedAccount')
const { theme } = useTheme()
const [avatarLoaded, setAvatarLoaded] = useState(false)
@ -53,7 +54,7 @@ const AccountInformation: React.FC<Props> = ({ account }) => {
>
<ParseContent
content={field.name}
size={constants.FONT_SIZE_M}
size={StyleConstants.Font.Size.M}
emojis={account.emojis}
showFullLink
/>{' '}
@ -62,7 +63,7 @@ const AccountInformation: React.FC<Props> = ({ account }) => {
<Text style={{ width: '70%', color: theme.primary }}>
<ParseContent
content={field.value}
size={constants.FONT_SIZE_M}
size={StyleConstants.Font.Size.M}
emojis={account.emojis}
showFullLink
/>
@ -76,7 +77,7 @@ const AccountInformation: React.FC<Props> = ({ account }) => {
<View style={styles.note}>
<ParseContent
content={account.note}
size={constants.FONT_SIZE_M}
size={StyleConstants.Font.Size.M}
emojis={account.emojis}
/>
</View>
@ -84,19 +85,20 @@ const AccountInformation: React.FC<Props> = ({ account }) => {
{account?.created_at && (
<View style={styles.created_at}>
<Feather name='calendar' size={constants.FONT_SIZE_M + 2} />
<Feather name='calendar' size={StyleConstants.Font.Size.M + 2} />
<Text
style={{
color: theme.primary,
fontSize: constants.FONT_SIZE_M,
marginLeft: constants.SPACING_XS
fontSize: StyleConstants.Font.Size.M,
marginLeft: StyleConstants.Spacing.XS
}}
>
{new Date(account.created_at).toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
{t('content.created_at', {
date: new Date(account.created_at).toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
})}
</Text>
</View>
@ -104,13 +106,19 @@ const AccountInformation: React.FC<Props> = ({ account }) => {
<View style={styles.summary}>
<Text style={{ color: theme.primary }}>
{account?.statuses_count}
{t('content.summary.statuses_count', {
count: account?.statuses_count
})}
</Text>
<Text style={{ color: theme.primary }}>
{account?.followers_count}
{t('content.summary.followers_count', {
count: account?.followers_count
})}
</Text>
<Text style={{ color: theme.primary }}>
{account?.following_count}
{t('content.summary.following_count', {
count: account?.following_count
})}
</Text>
</View>
</View>
@ -119,33 +127,33 @@ const AccountInformation: React.FC<Props> = ({ account }) => {
const styles = StyleSheet.create({
information: {
marginTop: -30 - constants.GLOBAL_PAGE_PADDING,
padding: constants.GLOBAL_PAGE_PADDING
marginTop: -30 - StyleConstants.Spacing.Global.PagePadding,
padding: StyleConstants.Spacing.Global.PagePadding
},
avatar: {
width: constants.AVATAR_L,
height: constants.AVATAR_L,
width: StyleConstants.Avatar.L,
height: StyleConstants.Avatar.L,
borderRadius: 8
},
display_name: {
fontSize: constants.FONT_SIZE_L,
fontWeight: 'bold',
marginTop: constants.SPACING_M,
marginBottom: constants.SPACING_XS
fontSize: StyleConstants.Font.Size.L,
fontWeight: StyleConstants.Font.Weight.Bold,
marginTop: StyleConstants.Spacing.M,
marginBottom: StyleConstants.Spacing.XS
},
account: {
fontSize: constants.FONT_SIZE_M,
marginBottom: constants.SPACING_S
fontSize: StyleConstants.Font.Size.M,
marginBottom: StyleConstants.Spacing.S
},
fields: {
marginBottom: constants.SPACING_S
marginBottom: StyleConstants.Spacing.S
},
note: {
marginBottom: constants.SPACING_M
marginBottom: StyleConstants.Spacing.M
},
created_at: {
flexDirection: 'row',
marginBottom: constants.SPACING_M
marginBottom: StyleConstants.Spacing.M
},
summary: {
flexDirection: 'row',

View File

@ -3,12 +3,14 @@ import { Dimensions, FlatList, View } from 'react-native'
import SegmentedControl from '@react-native-community/segmented-control'
import Timeline from 'src/components/Timelines/Timeline'
import { useTranslation } from 'react-i18next'
export interface Props {
id: Mastodon.Account['id']
}
const AccountToots: React.FC<Props> = ({ id }) => {
const { t } = useTranslation('sharedAccount')
const [segment, setSegment] = useState(0)
const [segmentManuallyTriggered, setSegmentManuallyTriggered] = useState(
false
@ -24,7 +26,11 @@ const AccountToots: React.FC<Props> = ({ id }) => {
return (
<>
<SegmentedControl
values={['嘟嘟', '嘟嘟和回复', '媒体']}
values={[
t('content.segments.left'),
t('content.segments.middle'),
t('content.segments.right')
]}
selectedIndex={segment}
onChange={({ nativeEvent }) => {
setSegmentManuallyTriggered(true)

View File

@ -1,7 +1,12 @@
import React from 'react'
import { useNavigation } from '@react-navigation/native'
import React, { useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
import { WebView } from 'react-native-webview'
// Update page title
import { HeaderLeft, HeaderRight } from 'src/components/Header'
const Stack = createNativeStackNavigator()
export interface Props {
route: {
@ -16,7 +21,42 @@ const ScreenSharedWebview: React.FC<Props> = ({
params: { uri }
}
}) => {
return <WebView source={{ uri: uri }} />
const navigation = useNavigation()
const { t } = useTranslation('sharedWebview')
const [title, setTitle] = useState<string>(t('heading.loading'))
const webview = useRef<WebView>(null)
return (
<Stack.Navigator>
<Stack.Screen
name='Screen-Shared-Webview-Root'
options={{
title,
headerLeft: () => (
<HeaderLeft
icon='chevron-down'
onPress={() => navigation.goBack()}
/>
),
headerRight: () => (
<HeaderRight
icon='refresh-cw'
onPress={() => webview.current?.reload()}
/>
)
}}
>
{() => (
<WebView
ref={webview}
source={{ uri }}
onLoad={({ nativeEvent }) => setTitle(nativeEvent.title)}
onError={() => setTitle(t('heading.error'))}
/>
)}
</Stack.Screen>
</Stack.Navigator>
)
}
export default ScreenSharedWebview

View File

@ -6,8 +6,11 @@ import ScreenSharedToot from 'src/screens/Shared/Toot'
import ScreenSharedWebview from 'src/screens/Shared/Webview'
import Compose from 'src/screens/Shared/Compose'
import ScreenSharedSearch from './Search'
import { useTranslation } from 'react-i18next'
const sharedScreens = (Stack: any) => {
const { t } = useTranslation()
return [
<Stack.Screen
key='Screen-Shared-Account'
@ -32,16 +35,16 @@ const sharedScreens = (Stack: any) => {
name='Screen-Shared-Toot'
component={ScreenSharedToot}
options={() => ({
title: '对话'
title: t('sharedToot:heading')
})}
/>,
<Stack.Screen
key='Screen-Shared-Webview'
name='Screen-Shared-Webview'
component={ScreenSharedWebview}
// options={({ route }) => ({
// title: `${route.params.domain}`
// })}
options={() => ({
stackPresentation: 'modal'
})}
/>,
<Stack.Screen
key='Screen-Shared-Compose'

View File

@ -1,5 +1,7 @@
import { store } from 'src/store'
const relativeTime = (date: string) => {
let units = {
const units = {
year: 24 * 60 * 60 * 1000 * 365,
month: (24 * 60 * 60 * 1000 * 365) / 12,
day: 24 * 60 * 60 * 1000,
@ -8,14 +10,20 @@ const relativeTime = (date: string) => {
second: 1000
}
let rtf = new Intl.RelativeTimeFormat('zh', { numeric: 'auto' })
const rtf = new Intl.RelativeTimeFormat(store.getState().settings.language, {
numeric: 'auto'
})
let elapsed: number = new Date(date) - new Date()
const elapsed = +new Date(date) - +new Date()
// "Math.abs" accounts for both "past" & "future" scenarios
for (var u in units)
if (Math.abs(elapsed) > units[u] || u == 'second')
for (const u in units) {
// @ts-ignore
if (Math.abs(elapsed) > units[u] || u == 'second') {
// @ts-ignore
return rtf.format(Math.round(elapsed / units[u]), u)
}
}
}
export default relativeTime

View File

@ -1,19 +1,30 @@
export default {
FONT_SIZE_S: 12,
FONT_SIZE_M: 14,
FONT_SIZE_L: 18,
const Base = 4
FONT_WEIGHT_BOLD: '600',
export const StyleConstants = {
Font: {
Size: {
S: 12,
M: 14,
L: 18
},
Weight: {
Bold: '600' as '600'
}
},
SPACING_XS: 4,
SPACING_S: 8,
SPACING_M: 16,
SPACING_L: 24,
SPACING_XL: 40,
Spacing: {
XS: Base,
S: Base * 2,
M: Base * 4,
L: Base * 6,
XL: Base * 10,
Global: {
PagePadding: Base * 6
}
},
GLOBAL_PAGE_PADDING: 24, // SPACING_M
GLOBAL_SPACING_BASE: 8, // SPACING_S
AVATAR_S: 52,
AVATAR_L: 104
Avatar: {
S: 52,
L: 104
}
}