diff --git a/app/locales/en/translation.json b/app/locales/en/translation.json
index 715a0b8..9e5446d 100644
--- a/app/locales/en/translation.json
+++ b/app/locales/en/translation.json
@@ -362,6 +362,9 @@
"submit": "Submit"
}
},
+ "homePage":{
+ "searchPlaceholder": "Search products"
+ },
"searchCountry": "Search country",
"noCountriesFound": "No countries found"
}
\ No newline at end of file
diff --git a/app/locales/fr/translation.json b/app/locales/fr/translation.json
index 017dd57..665ac2a 100644
--- a/app/locales/fr/translation.json
+++ b/app/locales/fr/translation.json
@@ -356,6 +356,10 @@
"error": "Une erreur s'est produite. Veuillez réessayer.",
"submit": "Soumettre"
}
+
+ },
+ "homePage":{
+ "searchPlaceholder": "Rechercher des produits"
},
"searchCountry": "Rechercher un pays",
"noCountriesFound": "Aucun pays trouvé"
diff --git a/app/screens/CartScreen.tsx b/app/screens/CartScreen.tsx
index 3efc582..84b0200 100644
--- a/app/screens/CartScreen.tsx
+++ b/app/screens/CartScreen.tsx
@@ -501,9 +501,9 @@ export const CartScreen = () => {
{/* Replace SVG with actual icon component or image */}
-
+ {/* */}
- Panier (5)
+ {/* Panier (5) */}
{cartList.map((item, index1) => (
diff --git a/app/screens/HomeScreen.tsx b/app/screens/HomeScreen.tsx
index f6e5545..fe1c92d 100644
--- a/app/screens/HomeScreen.tsx
+++ b/app/screens/HomeScreen.tsx
@@ -756,7 +756,7 @@ export const HomeScreen = () => {
onPress={navigateToSearch}
>
- 搜索商品
+ {t("homePage.searchPlaceholder")}
setShowImagePickerModal(true)}
diff --git a/app/screens/ProductDetailScreen.tsx b/app/screens/ProductDetailScreen.tsx
index b365df6..13034a7 100644
--- a/app/screens/ProductDetailScreen.tsx
+++ b/app/screens/ProductDetailScreen.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useCallback } from "react";
+import React, { useEffect, useCallback, useState } from "react";
import {
View,
Text,
@@ -15,7 +15,8 @@ import {
InteractionManager,
Platform,
StatusBar,
- SafeAreaView
+ SafeAreaView,
+ Modal
} from "react-native";
import fontSize from "../utils/fontsizeUtils";
import widthUtils from "../utils/widthUtils";
@@ -26,13 +27,14 @@ import ShoppingCartIcon from "../components/ShoppingCartIcon";
import HeartIcon from "../components/HeartIcon";
import HeartRedIcon from "../components/HeartIconRed";
import ShareIcon from "../components/ShareIcon";
-import { useState } from "react";
import { Image as ExpoImage, ImageBackground } from "expo-image";
import useUserStore from "../store/user";
import { getSubjectTransLanguage } from "../utils/languageUtils";
import { useTranslation } from "react-i18next";
import { getBurialPointData } from "../store/burialPoint";
import useBurialPointStore from "../store/burialPoint";
+import * as ImagePicker from "expo-image-picker";
+import * as FileSystem from "expo-file-system";
import {
productApi,
@@ -79,6 +81,8 @@ export const ProductDetailScreen = () => {
);
const [priceSelectedSku, setPriceSelectedSku] = useState();
const [showBottomSheet, setShowBottomSheet] = useState(false);
+ const [showImagePickerModal, setShowImagePickerModal] = useState(false);
+ const [galleryUsed, setGalleryUsed] = useState(false);
const groupData = (
res: ProductDetailParams,
priceSelectedSku: SkuAttribute[]
@@ -386,6 +390,9 @@ export const ProductDetailScreen = () => {
navigation.navigate("Search");
});
}, [navigation]);
+ const handleCameraPress = useCallback(() => {
+ setShowImagePickerModal(true);
+ }, []);
const handleProductPress = useCallback(
(item: similar) => {
InteractionManager.runAfterInteractions(() => {
@@ -412,6 +419,123 @@ export const ProductDetailScreen = () => {
));
};
+ // 清理expo-image-picker临时文件
+ const cleanupImagePickerCache = async () => {
+ try {
+ // Skip cache cleanup on web platform
+ if (Platform.OS === 'web') {
+ console.log('Cache cleanup skipped on web platform');
+ setGalleryUsed(false);
+ return;
+ }
+
+ // 相册选择后清理临时缓存
+ const cacheDir = `${FileSystem.cacheDirectory}ImagePicker`;
+ await FileSystem.deleteAsync(cacheDir, { idempotent: true });
+ console.log("已清理ImagePicker缓存");
+
+ // 立即重置状态,无需用户干预
+ setGalleryUsed(false);
+ } catch (error) {
+ console.log("清理缓存错误", error);
+ // Even if cleanup fails, reset the state
+ setGalleryUsed(false);
+ }
+ };
+
+ // 处理从相册选择
+ const handleChooseFromGallery = useCallback(async () => {
+ console.log("handleChooseFromGallery");
+ setShowImagePickerModal(false);
+
+ // 等待模态窗关闭后再执行
+ setTimeout(async () => {
+ try {
+ // 请求相册权限
+ const permissionResult =
+ await ImagePicker.requestMediaLibraryPermissionsAsync();
+ if (permissionResult.status !== "granted") {
+ console.log("相册权限被拒绝");
+ return;
+ }
+
+ // 打开相册
+ const result = await ImagePicker.launchImageLibraryAsync({
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ allowsEditing: true,
+ aspect: [4, 3],
+ quality: 1,
+ });
+
+ if (!result.canceled && result.assets && result.assets.length > 0) {
+ console.log("相册选择成功:", result.assets[0].uri);
+
+ await cleanupImagePickerCache();
+ navigation.navigate("ImageSearchResultScreen", {
+ image: result.assets[0].uri,
+ type: 1,
+ });
+ }
+ } catch (error: any) {
+ console.error("相册错误:", error);
+ // 出错时也清理缓存
+ await cleanupImagePickerCache();
+ }
+ }, 500);
+ }, [navigation, userStore.user]);
+
+ // 处理相机拍照
+ const handleTakePhoto = useCallback(async () => {
+ console.log("handleTakePhoto");
+ setShowImagePickerModal(false);
+
+ // 等待模态窗关闭后再执行
+ setTimeout(async () => {
+ try {
+ const permissionResult =
+ await ImagePicker.requestCameraPermissionsAsync();
+ if (permissionResult.status !== "granted") {
+ console.log("相机权限被拒绝");
+ return;
+ }
+
+ const result = await ImagePicker.launchCameraAsync({
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ allowsEditing: true,
+ aspect: [4, 3],
+ quality: 1,
+ });
+
+ if (!result.canceled && result.assets && result.assets.length > 0) {
+ console.log("拍照成功:", result.assets[0].uri);
+
+ // 使用后清理缓存
+ await cleanupImagePickerCache();
+ navigation.navigate("ImageSearchResultScreen", {
+ image: result.assets[0].uri,
+ type: 1,
+ });
+ }
+ } catch (error: any) {
+ console.error("相机错误:", error);
+ // 出错时也清理缓存
+ await cleanupImagePickerCache();
+ }
+ }, 500);
+ }, [navigation, userStore.user]);
+
+ // 重置应用状态函数
+ const resetAppState = useCallback(() => {
+ // 重置标记
+ setGalleryUsed(false);
+
+ // 清理缓存
+ cleanupImagePickerCache();
+
+ // 提示用户
+ Alert.alert("已重置", "现在您可以使用相机功能了");
+ }, []);
+
return (
@@ -431,10 +555,14 @@ export const ProductDetailScreen = () => {
>
-
- 搜索
-
-
+
+
+ 搜索
+
+
+
+
+
{
@@ -830,6 +958,57 @@ export const ProductDetailScreen = () => {
)}
+
+ {/* Image Picker Modal */}
+ setShowImagePickerModal(false)}
+ >
+ setShowImagePickerModal(false)}
+ >
+
+ {!galleryUsed ? (
+ // 正常状态,显示相机选项
+
+
+ 拍照
+
+ ) : (
+ // 已使用相册状态,显示重置选项
+
+ 重置相机功能
+
+ )}
+
+
+
+
+ 从相册选择
+
+
+ setShowImagePickerModal(false)}
+ >
+ 取消
+
+
+
+
);
};
@@ -1560,4 +1739,42 @@ const styles = StyleSheet.create({
backgroundColor: '#e0e0e0',
borderRadius: 3,
},
+ imagePickerOverlay: {
+ flex: 1,
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
+ justifyContent: "flex-end",
+ },
+ imagePickerContent: {
+ backgroundColor: "#fff",
+ borderTopLeftRadius: 10,
+ borderTopRightRadius: 10,
+ paddingTop: 20,
+ },
+ imagePickerOption: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "center",
+ paddingVertical: 15,
+ },
+ imagePickerText: {
+ fontSize: fontSize(16),
+ color: "#333",
+ marginLeft: 10,
+ },
+ imagePickerDivider: {
+ height: 1,
+ backgroundColor: "#eee",
+ marginHorizontal: 20,
+ },
+ imagePickerCancelButton: {
+ alignItems: "center",
+ paddingVertical: 15,
+ borderTopWidth: 1,
+ borderTopColor: "#eee",
+ marginTop: 10,
+ },
+ imagePickerCancelText: {
+ fontSize: fontSize(16),
+ color: "#333",
+ },
});