Browse Source

日常开发

林旭祥 2 days ago
parent
commit
573e0ddeaf
8 changed files with 173 additions and 12 deletions
  1. 4 6
      App.tsx
  2. 2 2
      index.js
  3. 99 1
      package-lock.json
  4. 3 0
      package.json
  5. 28 0
      src/i18n/index.js
  6. 14 0
      src/i18n/lang/en.js
  7. 14 0
      src/i18n/lang/zh.js
  8. 9 3
      src/pages/Team/index.tsx

+ 4 - 6
App.tsx

@@ -108,17 +108,16 @@ function App(): React.JSX.Element {
     <NavigationContainer>
       <Stack.Navigator initialRouteName="Login">
         <Stack.Screen
-          name="Login"
-          component={LoginScreen}
+          name="MainTabs"
+          component={TabNavigator}
           options={{
             headerBackVisible: false,
             headerShown: false,
           }}
         />
-        
         <Stack.Screen
-          name="MainTabs"
-          component={TabNavigator}
+          name="Login"
+          component={LoginScreen}
           options={{
             headerBackVisible: false,
             headerShown: false,
@@ -130,4 +129,3 @@ function App(): React.JSX.Element {
 }
 
 export default App;
-    

+ 2 - 2
index.js

@@ -2,9 +2,9 @@
  * @format
  */
 
-import {AppRegistry} from 'react-native';
+import { AppRegistry } from 'react-native';
 import App from './App';
-import {name as appName} from './app.json';
+import { name as appName } from './app.json';
 import api from './src/api/index';
 import utils from './src/utils/index';
 global.$http = api;

+ 99 - 1
package-lock.json

@@ -14,9 +14,12 @@
         "@react-navigation/native-stack": "^7.3.25",
         "axios": "^1.11.0",
         "dayjs": "^1.11.13",
+        "i18next": "^25.4.2",
         "react": "19.1.0",
+        "react-i18next": "^15.7.3",
         "react-native": "0.81.0",
         "react-native-fs": "^2.20.0",
+        "react-native-localize": "^3.5.2",
         "react-native-safe-area-context": "^5.6.1",
         "react-native-screens": "^4.15.2",
         "react-native-toast-message": "^2.3.3",
@@ -6987,6 +6990,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/html-parse-stringify": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+      "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+      "license": "MIT",
+      "dependencies": {
+        "void-elements": "3.1.0"
+      }
+    },
     "node_modules/http-errors": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -7035,6 +7047,37 @@
         "node": ">=10.17.0"
       }
     },
+    "node_modules/i18next": {
+      "version": "25.4.2",
+      "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.4.2.tgz",
+      "integrity": "sha512-gD4T25a6ovNXsfXY1TwHXXXLnD/K2t99jyYMCSimSCBnBRJVQr5j+VAaU83RJCPzrTGhVQ6dqIga66xO2rtd5g==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://locize.com"
+        },
+        {
+          "type": "individual",
+          "url": "https://locize.com/i18next.html"
+        },
+        {
+          "type": "individual",
+          "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.27.6"
+      },
+      "peerDependencies": {
+        "typescript": "^5"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/iconv-lite": {
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -10226,6 +10269,32 @@
         "react": ">=17.0.0"
       }
     },
+    "node_modules/react-i18next": {
+      "version": "15.7.3",
+      "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.7.3.tgz",
+      "integrity": "sha512-AANws4tOE+QSq/IeMF/ncoHlMNZaVLxpa5uUGW1wjike68elVYr0018L9xYoqBr1OFO7G7boDPrbn0HpMCJxTw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.27.6",
+        "html-parse-stringify": "^3.0.1"
+      },
+      "peerDependencies": {
+        "i18next": ">= 25.4.1",
+        "react": ">= 16.8.0",
+        "typescript": "^5"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/react-is": {
       "version": "18.3.1",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
@@ -10318,6 +10387,26 @@
         "react-native": "*"
       }
     },
+    "node_modules/react-native-localize": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/react-native-localize/-/react-native-localize-3.5.2.tgz",
+      "integrity": "sha512-HfQdwv5sRjh4AQ8a97OTjXYcxPNRlBxiQb861c7Ob6mRuNYCPtaJ45QTcZxZr31vAM3THvtOBp1soqWlQFxjnA==",
+      "license": "MIT",
+      "peerDependencies": {
+        "@expo/config-plugins": "^9.0.0 || ^10.0.0",
+        "react": "*",
+        "react-native": "*",
+        "react-native-macos": "*"
+      },
+      "peerDependenciesMeta": {
+        "@expo/config-plugins": {
+          "optional": true
+        },
+        "react-native-macos": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/react-native-safe-area-context": {
       "version": "5.6.1",
       "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.1.tgz",
@@ -11760,7 +11849,7 @@
       "version": "5.9.2",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
       "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
@@ -11965,6 +12054,15 @@
       "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
       "license": "MIT"
     },
+    "node_modules/void-elements": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+      "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/walker": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",

+ 3 - 0
package.json

@@ -16,9 +16,12 @@
     "@react-navigation/native-stack": "^7.3.25",
     "axios": "^1.11.0",
     "dayjs": "^1.11.13",
+    "i18next": "^25.4.2",
     "react": "19.1.0",
+    "react-i18next": "^15.7.3",
     "react-native": "0.81.0",
     "react-native-fs": "^2.20.0",
+    "react-native-localize": "^3.5.2",
     "react-native-safe-area-context": "^5.6.1",
     "react-native-screens": "^4.15.2",
     "react-native-toast-message": "^2.3.3",

+ 28 - 0
src/i18n/index.js

@@ -0,0 +1,28 @@
+import i18n from 'i18next';
+import { initReactI18next } from 'react-i18next';
+import * as RNLocalize from 'react-native-localize';
+
+// 导入语言包
+import en from './lang/en';
+import zh from './lang/zh';
+
+// 获取设备支持的语言
+const fallbackLanguage = { languageTag: 'en', isRTL: false };
+const { languageTag } = RNLocalize.findBestAvailableLanguage(['en', 'zh']) || fallbackLanguage;
+
+// 初始化 i18n
+i18n
+  .use(initReactI18next) // 将 i18n 传递给 react-i18next
+  .init({
+    resources: {
+      en: { translation: en },
+      zh: { translation: zh },
+    },
+    lng: languageTag, // 设置初始语言
+    fallbackLng: 'en', //  fallback 语言
+    interpolation: {
+      escapeValue: false, // react 已经处理了 XSS
+    },
+  });
+
+export default i18n;

+ 14 - 0
src/i18n/lang/en.js

@@ -0,0 +1,14 @@
+/*    
+hello: "Hello, {{name}}",//变量
+<Text>{t('welcome')}</Text>
+<Text>{t('hello', { name: '用户' })}</Text>
+<Button title="切换到中文" onPress={() => changeLanguage('zh')} />
+<Button title="Switch to English" onPress={() => changeLanguage('en')} />
+*/
+export default {
+    team: "Team",
+    data: "Data",
+    play: "Play",
+    match: "Match",
+    me: "Me",
+};

+ 14 - 0
src/i18n/lang/zh.js

@@ -0,0 +1,14 @@
+/*    
+hello: "Hello, {{name}}",//变量
+<Text>{t('welcome')}</Text>
+<Text>{t('hello', { name: '用户' })}</Text>
+<Button title="切换到中文" onPress={() => changeLanguage('zh')} />
+<Button title="Switch to English" onPress={() => changeLanguage('en')} />
+*/
+export default {
+  team: "球队",
+  data: "数据",
+  play: "PLAY",
+  match: "赛事",
+  me: "我的",
+};

+ 9 - 3
src/pages/Team/index.tsx

@@ -1,16 +1,23 @@
 import React from 'react';
-import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
+import { StyleSheet, View, Text, TouchableOpacity, Button } from 'react-native';
 import { useNavigation } from '@react-navigation/native';
+// import { useTranslation } from 'react-i18next';
+// const { t, i18n } = useTranslation();
 
 const TeamScreen = () => {
   const navigation = useNavigation();
   const getJump = async (data) => {
     navigation.navigate(data);
   };
+
+  const changeLanguage = async () => {
+    // i18n.changeLanguage('en');
+  };
   return (
     <View style={styles.main}>
+      <Button title="切换语言" onPress={changeLanguage} />
       <Text>
-球队
+        球队
       </Text>
     </View>
   );
@@ -18,7 +25,6 @@ const TeamScreen = () => {
 
 const styles = StyleSheet.create({
   main: {
-    paddingTop: 50,
   },
 });