Browse Source

翻译

main
Mac 2 weeks ago
parent
commit
627eb6e1a8
  1. 201
      app/screens/ProductDetailScreen.tsx
  2. 77
      app/screens/setting/SettingList.tsx
  3. 3
      app/services/api/productApi.ts
  4. 48
      app/utils/languageUtils.ts

201
app/screens/ProductDetailScreen.tsx

@ -16,7 +16,7 @@ import {
Platform, Platform,
StatusBar, StatusBar,
SafeAreaView, SafeAreaView,
Modal Modal,
} from "react-native"; } from "react-native";
import fontSize from "../utils/fontsizeUtils"; import fontSize from "../utils/fontsizeUtils";
import widthUtils from "../utils/widthUtils"; import widthUtils from "../utils/widthUtils";
@ -29,13 +29,12 @@ import HeartRedIcon from "../components/HeartIconRed";
import ShareIcon from "../components/ShareIcon"; import ShareIcon from "../components/ShareIcon";
import { Image as ExpoImage, ImageBackground } from "expo-image"; import { Image as ExpoImage, ImageBackground } from "expo-image";
import useUserStore from "../store/user"; import useUserStore from "../store/user";
import { getSubjectTransLanguage } from "../utils/languageUtils"; import { getSubjectTransLanguage,getSkuTransLanguage } from "../utils/languageUtils";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { getBurialPointData } from "../store/burialPoint"; import { getBurialPointData } from "../store/burialPoint";
import useBurialPointStore from "../store/burialPoint"; import useBurialPointStore from "../store/burialPoint";
import * as ImagePicker from "expo-image-picker"; import * as ImagePicker from "expo-image-picker";
import * as FileSystem from "expo-file-system"; import * as FileSystem from "expo-file-system";
import { import {
productApi, productApi,
ProductDetailParams, ProductDetailParams,
@ -91,18 +90,18 @@ export const ProductDetailScreen = () => {
// 遍历数据 // 遍历数据
res.skus.forEach((item) => { res.skus.forEach((item) => {
item.attributes.forEach((attribute) => { item.attributes.forEach((attribute) => {
const { attribute_name, value } = attribute; const { attribute_name_trans, value } = attribute;
// 如果结果对象中没有对应的属性名,则创建一个空数组 // 如果结果对象中没有对应的属性名,则创建一个空数组
if (!result[attribute_name]) { if (!result[attribute_name_trans]) {
result[attribute_name] = []; result[attribute_name_trans] = [];
} }
// 如果当前属性的值(value)已经存在于该组内,跳过 // 如果当前属性的值(value)已经存在于该组内,跳过
if ( if (
!result[attribute_name].some( !result[attribute_name_trans].some(
(existingAttribute: any) => existingAttribute.value === value (existingAttribute: any) => existingAttribute.value === value
) )
) { ) {
result[attribute_name].push(attribute); result[attribute_name_trans].push(attribute);
} }
}); });
}); });
@ -128,7 +127,10 @@ export const ProductDetailScreen = () => {
// Add has_image to the list item // Add has_image to the list item
list.push({ list.push({
attribute_name: attributeName, attribute_name: attributeName,
has_image: withImage.length > 0, // If there are any items with images, set has_image to true attribute_name_trans: attributeName,
attribute_name_trans_ar: attributeName,
attribute_name_trans_en: attributeName,
has_image: withImage.length > 0,
attributes: [...withImage, ...withoutImage], attributes: [...withImage, ...withoutImage],
}); });
} }
@ -325,9 +327,9 @@ export const ProductDetailScreen = () => {
imageUrls.length > 5 ? imageUrls.slice(0, 5) : imageUrls; imageUrls.length > 5 ? imageUrls.slice(0, 5) : imageUrls;
setImageUrls(limitedImageUrls); setImageUrls(limitedImageUrls);
setGroupList(list); setGroupList(list);
const previousScreen = navigation.getState().routes[navigation.getState().index - 1];
const previousScreen =
navigation.getState().routes[navigation.getState().index - 1];
const data = { const data = {
offer_id: res.offer_id, offer_id: res.offer_id,
category_id: res.category_id, category_id: res.category_id,
@ -337,12 +339,9 @@ export const ProductDetailScreen = () => {
product_name: res.subject, product_name: res.subject,
product_img: res.product_image_urls[0], product_img: res.product_image_urls[0],
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
} };
logViewProduct(data,previousScreen?.name as string); logViewProduct(data, previousScreen?.name as string);
console.log(getBurialPointData()); console.log(getBurialPointData());
} catch (error) { } catch (error) {
console.error("Error fetching product details:", error); console.error("Error fetching product details:", error);
} finally { } finally {
@ -389,7 +388,6 @@ export const ProductDetailScreen = () => {
navigation.navigate("Search"); navigation.navigate("Search");
}, [navigation]); }, [navigation]);
const handleCameraPress = useCallback(() => { const handleCameraPress = useCallback(() => {
setShowImagePickerModal(true); setShowImagePickerModal(true);
}, []); }, []);
@ -404,36 +402,35 @@ export const ProductDetailScreen = () => {
}, },
[navigation] [navigation]
); );
// Add this function to render skeleton UI // Add this function to render skeleton UI
const renderSkeletonItems = () => { const renderSkeletonItems = () => {
// Create an array of 5 skeleton items // Create an array of 5 skeleton items
return Array(5).fill(0).map((_, index) => ( return Array(5)
<View style={styles.productCard} key={`skeleton-${index}`}> .fill(0)
<View style={[styles.cardContainerWithPrice, styles.skeletonBox]} /> .map((_, index) => (
<View style={styles.priceContainerFlex}> <View style={styles.productCard} key={`skeleton-${index}`}>
<View style={[styles.skeletonText, { width: 50 }]} /> <View style={[styles.cardContainerWithPrice, styles.skeletonBox]} />
<View style={[styles.skeletonText, { width: 30, marginLeft: 5 }]} /> <View style={styles.priceContainerFlex}>
<View style={[styles.skeletonText, { width: 50 }]} />
<View style={[styles.skeletonText, { width: 30, marginLeft: 5 }]} />
</View>
</View> </View>
</View> ));
));
}; };
// 清理expo-image-picker临时文件 // 清理expo-image-picker临时文件
const cleanupImagePickerCache = async () => { const cleanupImagePickerCache = async () => {
try { try {
// Skip cache cleanup on web platform // Skip cache cleanup on web platform
if (Platform.OS === 'web') { if (Platform.OS === "web") {
console.log('Cache cleanup skipped on web platform'); console.log("Cache cleanup skipped on web platform");
setGalleryUsed(false); setGalleryUsed(false);
return; return;
} }
// 相册选择后清理临时缓存 // 相册选择后清理临时缓存
const cacheDir = `${FileSystem.cacheDirectory}ImagePicker`; const cacheDir = `${FileSystem.cacheDirectory}ImagePicker`;
await FileSystem.deleteAsync(cacheDir, { idempotent: true }); await FileSystem.deleteAsync(cacheDir, { idempotent: true });
console.log("已清理ImagePicker缓存"); console.log("已清理ImagePicker缓存");
// 立即重置状态,无需用户干预 // 立即重置状态,无需用户干预
setGalleryUsed(false); setGalleryUsed(false);
} catch (error) { } catch (error) {
@ -442,12 +439,10 @@ export const ProductDetailScreen = () => {
setGalleryUsed(false); setGalleryUsed(false);
} }
}; };
// 处理从相册选择 // 处理从相册选择
const handleChooseFromGallery = useCallback(async () => { const handleChooseFromGallery = useCallback(async () => {
console.log("handleChooseFromGallery"); console.log("handleChooseFromGallery");
setShowImagePickerModal(false); setShowImagePickerModal(false);
// 等待模态窗关闭后再执行 // 等待模态窗关闭后再执行
setTimeout(async () => { setTimeout(async () => {
try { try {
@ -458,7 +453,6 @@ export const ProductDetailScreen = () => {
console.log("相册权限被拒绝"); console.log("相册权限被拒绝");
return; return;
} }
// 打开相册 // 打开相册
const result = await ImagePicker.launchImageLibraryAsync({ const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images, mediaTypes: ImagePicker.MediaTypeOptions.Images,
@ -466,10 +460,8 @@ export const ProductDetailScreen = () => {
aspect: [4, 3], aspect: [4, 3],
quality: 1, quality: 1,
}); });
if (!result.canceled && result.assets && result.assets.length > 0) { if (!result.canceled && result.assets && result.assets.length > 0) {
console.log("相册选择成功:", result.assets[0].uri); console.log("相册选择成功:", result.assets[0].uri);
await cleanupImagePickerCache(); await cleanupImagePickerCache();
navigation.navigate("ImageSearchResultScreen", { navigation.navigate("ImageSearchResultScreen", {
image: result.assets[0].uri, image: result.assets[0].uri,
@ -483,12 +475,10 @@ export const ProductDetailScreen = () => {
} }
}, 500); }, 500);
}, [navigation, userStore.user]); }, [navigation, userStore.user]);
// 处理相机拍照 // 处理相机拍照
const handleTakePhoto = useCallback(async () => { const handleTakePhoto = useCallback(async () => {
console.log("handleTakePhoto"); console.log("handleTakePhoto");
setShowImagePickerModal(false); setShowImagePickerModal(false);
// 等待模态窗关闭后再执行 // 等待模态窗关闭后再执行
setTimeout(async () => { setTimeout(async () => {
try { try {
@ -498,17 +488,14 @@ export const ProductDetailScreen = () => {
console.log("相机权限被拒绝"); console.log("相机权限被拒绝");
return; return;
} }
const result = await ImagePicker.launchCameraAsync({ const result = await ImagePicker.launchCameraAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images, mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true, allowsEditing: true,
aspect: [4, 3], aspect: [4, 3],
quality: 1, quality: 1,
}); });
if (!result.canceled && result.assets && result.assets.length > 0) { if (!result.canceled && result.assets && result.assets.length > 0) {
console.log("拍照成功:", result.assets[0].uri); console.log("拍照成功:", result.assets[0].uri);
// 使用后清理缓存 // 使用后清理缓存
await cleanupImagePickerCache(); await cleanupImagePickerCache();
navigation.navigate("ImageSearchResultScreen", { navigation.navigate("ImageSearchResultScreen", {
@ -523,19 +510,15 @@ export const ProductDetailScreen = () => {
} }
}, 500); }, 500);
}, [navigation, userStore.user]); }, [navigation, userStore.user]);
// 重置应用状态函数 // 重置应用状态函数
const resetAppState = useCallback(() => { const resetAppState = useCallback(() => {
// 重置标记 // 重置标记
setGalleryUsed(false); setGalleryUsed(false);
// 清理缓存 // 清理缓存
cleanupImagePickerCache(); cleanupImagePickerCache();
// 提示用户 // 提示用户
Alert.alert("已重置", "现在您可以使用相机功能了"); Alert.alert("已重置", "现在您可以使用相机功能了");
}, []); }, []);
return ( return (
<SafeAreaView style={styles.safeArea}> <SafeAreaView style={styles.safeArea}>
<StatusBar barStyle="dark-content" backgroundColor="#fff" /> <StatusBar barStyle="dark-content" backgroundColor="#fff" />
@ -555,18 +538,17 @@ export const ProductDetailScreen = () => {
> >
<BackIcon size={fontSize(20)} /> <BackIcon size={fontSize(20)} />
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.search} style={styles.search}
onPress={handleSearchPress} onPress={handleSearchPress}
activeOpacity={0.7} activeOpacity={0.7}
> >
<View style={{ width: '100%', alignItems: 'flex-start' }}> <View style={{ width: "100%", alignItems: "flex-start" }}>
<Text style={styles.searchText}>{t("search")}</Text> <Text style={styles.searchText}>{t("search")}</Text>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.searchIcon} style={styles.searchIcon}
onPress={() => { onPress={() => {
@ -660,7 +642,8 @@ export const ProductDetailScreen = () => {
}} }}
> >
<Text style={styles.activeIndexText}> <Text style={styles.activeIndexText}>
{activeIndex + 1}/{product?.product_image_urls?.length} {activeIndex + 1}/
{product?.product_image_urls?.length}
</Text> </Text>
</View> </View>
</View> </View>
@ -693,9 +676,10 @@ export const ProductDetailScreen = () => {
{userStore.user?.vip_level > 0 && ( {userStore.user?.vip_level > 0 && (
<> <>
<View style={styles.discountInfoContainer}> <View style={styles.discountInfoContainer}>
<Text style={styles.emphasizedTextWidget}>-5%</Text> <Text style={styles.emphasizedTextWidget}>
-5%
</Text>
</View> </View>
<View style={styles.priceInfoVip}> <View style={styles.priceInfoVip}>
<ImageBackground <ImageBackground
source={require("../../assets/img/vip1.png")} source={require("../../assets/img/vip1.png")}
@ -715,23 +699,28 @@ export const ProductDetailScreen = () => {
<View style={styles.blackThemeContainer}> <View style={styles.blackThemeContainer}>
{groupList.map((item, index) => {groupList.map((item, index) =>
item.has_image ? ( item.has_image ? (
<View key={item.attribute_name}> <View key={item.attribute_name_trans}>
<Text style={styles.uniqueTextBlock}> <Text style={styles.uniqueTextBlock}>
{item.attribute_name} :{" "} {item.attribute_name_trans} :{" "}
{ {
item.attributes.find((item) => item.has_color) // getSkuTransLanguage()
?.value item.attributes.find(
(item) => item.has_color
)?.value
} }
</Text> </Text>
<View style={styles.horizontalFlexContainer}> <View style={styles.horizontalFlexContainer}>
{getDisplayAttributes( {getDisplayAttributes(
item.attributes, item.attributes,
item.attribute_name item.attribute_name_trans
).map((attribute) => ( ).map((attribute) => (
<TouchableOpacity <TouchableOpacity
key={attribute.value} key={attribute.value}
onPress={() => onPress={() =>
handleColorSelect(attribute.value, index) handleColorSelect(
attribute.value,
index
)
} }
style={[ style={[
styles.colorImageContainer, styles.colorImageContainer,
@ -740,17 +729,19 @@ export const ProductDetailScreen = () => {
]} ]}
> >
<Image <Image
source={{ uri: attribute.sku_image_url }} source={{
uri: attribute.sku_image_url,
}}
style={styles.imageContainer} style={styles.imageContainer}
/> />
</TouchableOpacity> </TouchableOpacity>
))} ))}
{!expandedGroups[item.attribute_name] && {!expandedGroups[item.attribute_name_trans] &&
item.attributes.length > 6 && ( item.attributes.length > 6 && (
<TouchableOpacity <TouchableOpacity
style={styles.expandButton} style={styles.expandButton}
onPress={() => onPress={() =>
toggleExpand(item.attribute_name) toggleExpand(item.attribute_name_trans)
} }
> >
<Text style={styles.expandButtonText}> <Text style={styles.expandButtonText}>
@ -758,11 +749,11 @@ export const ProductDetailScreen = () => {
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
{expandedGroups[item.attribute_name] && ( {expandedGroups[item.attribute_name_trans] && (
<TouchableOpacity <TouchableOpacity
style={styles.expandButton} style={styles.expandButton}
onPress={() => onPress={() =>
toggleExpand(item.attribute_name) toggleExpand(item.attribute_name_trans)
} }
> >
<Text style={styles.expandButtonText}> <Text style={styles.expandButtonText}>
@ -793,14 +784,14 @@ export const ProductDetailScreen = () => {
)} )}
</View> </View>
) : ( ) : (
<View key={item.attribute_name}> <View key={item.attribute_name_trans}>
<Text style={styles.uniqueTextBlock}> <Text style={styles.uniqueTextBlock}>
{item.attribute_name} {item.attribute_name_trans}
</Text> </Text>
<View style={styles.horizontalFlexContainer}> <View style={styles.horizontalFlexContainer}>
{getDisplayAttributes( {getDisplayAttributes(
item.attributes, item.attributes,
item.attribute_name item.attribute_name_trans
).map((attribute) => ( ).map((attribute) => (
<TouchableOpacity <TouchableOpacity
key={attribute.value} key={attribute.value}
@ -824,12 +815,12 @@ export const ProductDetailScreen = () => {
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
))} ))}
{!expandedGroups[item.attribute_name] && {!expandedGroups[item.attribute_name_trans] &&
item.attributes.length > 6 && ( item.attributes.length > 6 && (
<TouchableOpacity <TouchableOpacity
style={styles.expandButton} style={styles.expandButton}
onPress={() => onPress={() =>
toggleExpand(item.attribute_name) toggleExpand(item.attribute_name_trans)
} }
> >
<Text style={styles.expandButtonText}> <Text style={styles.expandButtonText}>
@ -837,11 +828,11 @@ export const ProductDetailScreen = () => {
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
{expandedGroups[item.attribute_name] && ( {expandedGroups[item.attribute_name_trans] && (
<TouchableOpacity <TouchableOpacity
style={styles.expandButton} style={styles.expandButton}
onPress={() => onPress={() =>
toggleExpand(item.attribute_name) toggleExpand(item.attribute_name_trans)
} }
> >
<Text style={styles.expandButtonText}> <Text style={styles.expandButtonText}>
@ -888,31 +879,32 @@ export const ProductDetailScreen = () => {
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.productGridContainer} contentContainerStyle={styles.productGridContainer}
> >
{isSimilarsFlag ? {isSimilarsFlag
similars?.map((item) => ( ? similars?.map((item) => (
<TouchableOpacity <TouchableOpacity
style={styles.productCard} style={styles.productCard}
key={item.offer_id} key={item.offer_id}
onPress={() => handleProductPress(item)} onPress={() => handleProductPress(item)}
> >
<View style={styles.cardContainerWithPrice}> <View style={styles.cardContainerWithPrice}>
<Image <Image
source={{ uri: item.product_image_urls[0] }} source={{ uri: item.product_image_urls[0] }}
style={styles.imageContainerCompact} style={styles.imageContainerCompact}
/> />
</View> </View>
<View style={styles.priceContainerFlex}> <View style={styles.priceContainerFlex}>
<Text style={styles.highlightedText1}> <Text style={styles.highlightedText1}>
{item.max_price} {item.max_price}
</Text> </Text>
<Text style={styles.highlightedTextWithBorder}> <Text
FCFA style={styles.highlightedTextWithBorder}
</Text> >
</View> FCFA
</TouchableOpacity> </Text>
)) </View>
: renderSkeletonItems() </TouchableOpacity>
} ))
: renderSkeletonItems()}
</ScrollView> </ScrollView>
</View> </View>
<View style={{ width: "100%" }}> <View style={{ width: "100%" }}>
@ -962,7 +954,7 @@ export const ProductDetailScreen = () => {
)} )}
</View> </View>
</View> </View>
{/* Image Picker Modal */} {/* Image Picker Modal */}
<Modal <Modal
visible={showImagePickerModal} visible={showImagePickerModal}
@ -994,16 +986,13 @@ export const ProductDetailScreen = () => {
<Text style={styles.imagePickerText}></Text> <Text style={styles.imagePickerText}></Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
<View style={styles.imagePickerDivider} /> <View style={styles.imagePickerDivider} />
<TouchableOpacity <TouchableOpacity
style={styles.imagePickerOption} style={styles.imagePickerOption}
onPress={handleChooseFromGallery} onPress={handleChooseFromGallery}
> >
<Text style={styles.imagePickerText}></Text> <Text style={styles.imagePickerText}></Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.imagePickerCancelButton} style={styles.imagePickerCancelButton}
onPress={() => setShowImagePickerModal(false)} onPress={() => setShowImagePickerModal(false)}
@ -1019,15 +1008,15 @@ export const ProductDetailScreen = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
safeArea: { safeArea: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
safeAreaContent: { safeAreaContent: {
flex: 1, flex: 1,
paddingTop: Platform.OS === 'android' ? 0 : 0, paddingTop: Platform.OS === "android" ? 0 : 0,
}, },
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
scrollView: { scrollView: {
flex: 1, flex: 1,
@ -1306,7 +1295,7 @@ const styles = StyleSheet.create({
fontSize: fontSize(18), fontSize: fontSize(18),
color: "#f1c355", color: "#f1c355",
textAlign: "center", textAlign: "center",
marginLeft:2 marginLeft: 2,
}, },
emphasizedTextVip: { emphasizedTextVip: {
fontStyle: "italic", fontStyle: "italic",
@ -1733,14 +1722,14 @@ const styles = StyleSheet.create({
color: "#666", color: "#666",
}, },
skeletonBox: { skeletonBox: {
backgroundColor: '#e0e0e0', backgroundColor: "#e0e0e0",
height: widthUtils(90, 90).height, height: widthUtils(90, 90).height,
width: widthUtils(90, 90).width, width: widthUtils(90, 90).width,
borderRadius: 5, borderRadius: 5,
}, },
skeletonText: { skeletonText: {
height: 16, height: 16,
backgroundColor: '#e0e0e0', backgroundColor: "#e0e0e0",
borderRadius: 3, borderRadius: 3,
}, },
imagePickerOverlay: { imagePickerOverlay: {

77
app/screens/setting/SettingList.tsx

@ -1,4 +1,12 @@
import { View, Text, StyleSheet, TouchableOpacity, SafeAreaView, StatusBar, Platform } from "react-native"; import {
View,
Text,
StyleSheet,
TouchableOpacity,
SafeAreaView,
StatusBar,
Platform,
} from "react-native";
import BackIcon from "../../components/BackIcon"; import BackIcon from "../../components/BackIcon";
import fontSize from "../../utils/fontsizeUtils"; import fontSize from "../../utils/fontsizeUtils";
import LeftArrowIcon from "../../components/DownArrowIcon"; import LeftArrowIcon from "../../components/DownArrowIcon";
@ -8,24 +16,26 @@ import { useState, useEffect } from "react";
import { settingApi, MySetting } from "../../services/api/setting"; import { settingApi, MySetting } from "../../services/api/setting";
import { RootStackParamList } from "../../navigation/types"; import { RootStackParamList } from "../../navigation/types";
import { eventBus } from "../../utils/eventBus"; import { eventBus } from "../../utils/eventBus";
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from "@react-native-async-storage/async-storage";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import useUserStore from "../../store/user";
export const SettingList = () => { export const SettingList = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [mySetting, setMySetting] = useState<MySetting>(); const [mySetting, setMySetting] = useState<MySetting>();
const { user } = useUserStore();
const getMySetting = async () => { const getMySetting = async () => {
const res = await settingApi.getMySetting() const res = await settingApi.getMySetting();
console.log("MySetting:");
console.log(res);
setMySetting(res); setMySetting(res);
} };
useEffect(() => { useEffect(() => {
getMySetting(); if (user?.user_id) {
const refreshSetting = () => {
getMySetting(); getMySetting();
} }
const refreshSetting = () => {
getMySetting();
};
eventBus.on("refreshSetting", refreshSetting); eventBus.on("refreshSetting", refreshSetting);
return () => { return () => {
eventBus.off("refreshSetting", refreshSetting); eventBus.off("refreshSetting", refreshSetting);
@ -39,15 +49,13 @@ export const SettingList = () => {
<StatusBar barStyle="dark-content" backgroundColor="#fff" /> <StatusBar barStyle="dark-content" backgroundColor="#fff" />
<View style={styles.safeAreaContent}> <View style={styles.safeAreaContent}>
<View style={styles.header}> <View style={styles.header}>
<TouchableOpacity <TouchableOpacity onPress={() => navigation.goBack()}>
onPress={() => navigation.goBack()}
>
<BackIcon size={fontSize(24)} /> <BackIcon size={fontSize(24)} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.headerTitle}>{t("settings.title")}</Text> <Text style={styles.headerTitle}>{t("settings.title")}</Text>
<View style={styles.placeholder} /> <View style={styles.placeholder} />
</View> </View>
<View style={styles.content}> <View style={styles.content}>
<View style={styles.item}> <View style={styles.item}>
<Text>{t("settings.profile")}</Text> <Text>{t("settings.profile")}</Text>
@ -70,19 +78,19 @@ export const SettingList = () => {
</View> </View>
<View style={styles.content}> <View style={styles.content}>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
if (mySetting?.language && mySetting?.currency) { if (mySetting?.language && mySetting?.currency) {
navigation.navigate("MyAddress"); navigation.navigate("MyAddress");
} }
}} }}
style={styles.item} style={styles.item}
> >
<Text>{t("settings.my_address")}</Text> <Text>{t("settings.my_address")}</Text>
<Text> <Text>
<LeftArrowIcon size={fontSize(20)} color="#acacac" /> <LeftArrowIcon size={fontSize(20)} color="#acacac" />
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
<View style={styles.item}> <View style={styles.item}>
<Text>{t("settings.feedback")}</Text> <Text>{t("settings.feedback")}</Text>
<Text> <Text>
@ -102,10 +110,13 @@ export const SettingList = () => {
</Text> </Text>
</View> </View>
<TouchableOpacity style={styles.item} onPress={() => { <TouchableOpacity
AsyncStorage.clear(); style={styles.item}
navigation.navigate("CountrySelect"); onPress={() => {
}}> AsyncStorage.clear();
navigation.navigate("CountrySelect");
}}
>
<Text>{t("settings.clear_cache")}</Text> <Text>{t("settings.clear_cache")}</Text>
<Text> <Text>
<LeftArrowIcon size={fontSize(20)} color="#acacac" /> <LeftArrowIcon size={fontSize(20)} color="#acacac" />
@ -115,9 +126,9 @@ export const SettingList = () => {
<View> <View>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
// if (mySetting?.language && mySetting?.currency) { // if (mySetting?.language && mySetting?.currency) {
navigation.navigate("CountrySetting", { mySetting }); navigation.navigate("CountrySetting", { mySetting });
// } // }
}} }}
style={styles.item} style={styles.item}
> >
@ -136,7 +147,7 @@ export const SettingList = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
safeArea: { safeArea: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
safeAreaContent: { safeAreaContent: {
flex: 1, flex: 1,

3
app/services/api/productApi.ts

@ -178,6 +178,9 @@ export type Products = Product[]
export interface ProductGroupList { export interface ProductGroupList {
attribute_name:string, attribute_name:string,
has_image:boolean, has_image:boolean,
attribute_name_trans:string,
attribute_name_trans_ar:string,
attribute_name_trans_en:string,
attributes:SkuAttribute[], attributes:SkuAttribute[],
value?:string value?:string
} }

48
app/utils/languageUtils.ts

@ -30,28 +30,28 @@ export const getSubjectTransLanguage = <T extends Record<string, any>>(data: T):
// export const getSkuTransLanguage = <T extends Record<string, any>>(data: T): string => { export const getSkuTransLanguage = <T extends Record<string, any>>(data: T): string => {
// // 获取当前i18n语言 // 获取当前i18n语言
// const currentLang = getCurrentLanguage(); const currentLang = getCurrentLanguage();
// // 特殊处理中文 // 特殊处理中文
// if (currentLang === 'zh' && 'value' in data) { if (currentLang === 'zh' && 'value' in data) {
// return data.value as string; return data.value as string;
// } }
// // 获取所有subject_trans开头的字段 // 获取所有subject_trans开头的字段
// const translationFields = Object.keys(data).filter(key => const translationFields = Object.keys(data).filter(key =>
// key.startsWith('value_trans') key.startsWith('value_trans')
// ); );
// // 查找匹配的字段 // 查找匹配的字段
// const matchedField = translationFields.find(field => { const matchedField = translationFields.find(field => {
// // 从字段名中提取语言代码 // 从字段名中提取语言代码
// const langCode = field.replace('value_trans_', ''); const langCode = field.replace('value_trans_', '');
// // 如果没有后缀,则为法语 // 如果没有后缀,则为法语
// return langCode === '' ? currentLang === 'fr' : langCode === currentLang; return langCode === '' ? currentLang === 'fr' : langCode === currentLang;
// }); });
// // 返回匹配的翻译值,如果没有匹配则返回法语 // 返回匹配的翻译值,如果没有匹配则返回法语
// return (data[matchedField || 'value_trans'] as string) || ''; return (data[matchedField || 'value_trans'] as string) || '';
// }; };

Loading…
Cancel
Save