mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Some translations are done
This commit is contained in:
		| @@ -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 }) => { | ||||
|   | ||||
| @@ -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' | ||||
|   } | ||||
| }) | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								src/components/Header.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/components/Header.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| import HeaderLeft from './Header/Left' | ||||
| import HeaderRight from './Header/Right' | ||||
|  | ||||
| export { HeaderLeft, HeaderRight } | ||||
							
								
								
									
										41
									
								
								src/components/Header/Left.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/components/Header/Left.tsx
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										52
									
								
								src/components/Header/Right.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/components/Header/Right.tsx
									
									
									
									
									
										Normal 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 | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										3
									
								
								src/components/NetworkState.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/components/NetworkState.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| import NetworkStateError from './NetworkState/Error' | ||||
|  | ||||
| export { NetworkStateError } | ||||
							
								
								
									
										20
									
								
								src/components/NetworkState/Error.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/components/NetworkState/Error.tsx
									
									
									
									
									
										Normal 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 | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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' | ||||
|   | ||||
| @@ -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%', | ||||
|   | ||||
| @@ -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%', | ||||
|   | ||||
| @@ -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} | ||||
|           /> | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -1,20 +1,5 @@ | ||||
| export default { | ||||
|   buttons: { | ||||
|     cancel: '取消' | ||||
|   }, | ||||
|   headers: { | ||||
|     local: { | ||||
|       segments: { | ||||
|         left: '我的关注', | ||||
|         right: '本站嘟嘟' | ||||
|       } | ||||
|     }, | ||||
|     public: { | ||||
|       segments: { | ||||
|         left: '跨站关注', | ||||
|         right: '外站嘟嘟' | ||||
|       } | ||||
|     }, | ||||
|     notifications: '我的通知' | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										9
									
								
								src/i18n/zh/screens/local.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/i18n/zh/screens/local.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| export default { | ||||
|   heading: { | ||||
|     segments: { | ||||
|       left: '我的关注', | ||||
|       right: '本站嘟嘟' | ||||
|     } | ||||
|   }, | ||||
|   content: {} | ||||
| } | ||||
| @@ -1,7 +1,12 @@ | ||||
| export default { | ||||
|   heading: '我的长毛象', | ||||
|   content: { | ||||
|     login: {}, | ||||
|     login: { | ||||
|       server: { | ||||
|         placeholder: '请输入服务器' | ||||
|       }, | ||||
|       button: '登录' | ||||
|     }, | ||||
|     collections: { | ||||
|       conversations: '$t(meConversations:heading)', | ||||
|       bookmarks: '$t(meBookmarks:heading)', | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export default { | ||||
|       } | ||||
|     }, | ||||
|     theme: { | ||||
|       heading: '颜色模式', | ||||
|       heading: '应用外观', | ||||
|       options: { | ||||
|         auto: '跟随系统', | ||||
|         light: '浅色模式', | ||||
|   | ||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/notifications.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/notifications.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| export default { | ||||
|   heading: '通知', | ||||
|   content: {} | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/i18n/zh/screens/public.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/i18n/zh/screens/public.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| export default { | ||||
|   heading: { | ||||
|     segments: { | ||||
|       left: '跨站关注', | ||||
|       right: '外站嘟嘟' | ||||
|     } | ||||
|   }, | ||||
|   content: {} | ||||
| } | ||||
							
								
								
									
										19
									
								
								src/i18n/zh/screens/sharedAccount.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/i18n/zh/screens/sharedAccount.ts
									
									
									
									
									
										Normal 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: '所有媒体' | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/sharedToot.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/sharedToot.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| export default { | ||||
|   heading: '对话', | ||||
|   content: {} | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/i18n/zh/screens/sharedWebview.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/i18n/zh/screens/sharedWebview.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| export default { | ||||
|   heading: { | ||||
|     loading: '加载中…', | ||||
|     error: '加载错误' | ||||
|   }, | ||||
|   content: {} | ||||
| } | ||||
| @@ -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' } | ||||
|       ]} | ||||
|     /> | ||||
|   ) | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -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'> | ||||
|         {() => | ||||
|   | ||||
| @@ -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' } | ||||
|       ]} | ||||
|     /> | ||||
|   ) | ||||
|   | ||||
| @@ -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', | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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' | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user