feat: 更新 UI 样式以及消息通知
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { AnimatedNumber } from '@/components/AnimatedNumber';
|
||||
import { FloatingFoodOverlay } from '@/components/FloatingFoodOverlay';
|
||||
import { ROUTES } from '@/constants/Routes';
|
||||
import { NutritionSummary } from '@/services/dietRecords';
|
||||
import { triggerLightHaptic } from '@/utils/haptics';
|
||||
@@ -7,7 +6,7 @@ import { NutritionGoals, calculateRemainingCalories } from '@/utils/nutrition';
|
||||
import dayjs from 'dayjs';
|
||||
import { router } from 'expo-router';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Animated, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { Animated, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import Svg, { Circle } from 'react-native-svg';
|
||||
|
||||
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
||||
@@ -107,7 +106,6 @@ export function NutritionRadarCard({
|
||||
onMealPress
|
||||
}: NutritionRadarCardProps) {
|
||||
const [currentMealType] = useState<'breakfast' | 'lunch' | 'dinner' | 'snack'>('breakfast');
|
||||
const [showFoodOverlay, setShowFoodOverlay] = useState(false);
|
||||
|
||||
const nutritionStats = useMemo(() => {
|
||||
return [
|
||||
@@ -138,25 +136,12 @@ export function NutritionRadarCard({
|
||||
router.push(ROUTES.NUTRITION_RECORDS);
|
||||
};
|
||||
|
||||
const handleAddFood = () => {
|
||||
triggerLightHaptic();
|
||||
setShowFoodOverlay(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.card} onPress={handleNavigateToRecords} activeOpacity={0.8}>
|
||||
<View style={styles.cardHeader}>
|
||||
<Text style={styles.cardTitle}>饮食分析</Text>
|
||||
<View style={styles.cardRightContainer}>
|
||||
<Text style={styles.cardSubtitle}>更新: {dayjs(nutritionSummary?.updatedAt).format('MM-DD HH:mm')}</Text>
|
||||
<TouchableOpacity style={styles.addButton} onPress={handleAddFood}>
|
||||
{/* <Ionicons name="add" size={16} color="#514b4bff" /> */}
|
||||
<Text style={{
|
||||
fontSize: 12,
|
||||
color: 'white'
|
||||
}}>添加+</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.cardSubtitle}>更新: {dayjs(nutritionSummary?.updatedAt).format('MM-DD HH:mm')}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.contentContainer}>
|
||||
@@ -228,12 +213,59 @@ export function NutritionRadarCard({
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 食物添加悬浮窗 */}
|
||||
<FloatingFoodOverlay
|
||||
visible={showFoodOverlay}
|
||||
onClose={() => setShowFoodOverlay(false)}
|
||||
mealType={currentMealType}
|
||||
/>
|
||||
{/* 添加食物选项 */}
|
||||
<View style={styles.foodOptionsContainer}>
|
||||
<TouchableOpacity
|
||||
style={styles.foodOptionItem}
|
||||
onPress={() => {
|
||||
triggerLightHaptic();
|
||||
router.push(`/food/camera?mealType=${currentMealType}`);
|
||||
}}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<View style={[styles.foodOptionIcon]}>
|
||||
<Image
|
||||
source={require('@/assets/images/icons/icon-camera.png')}
|
||||
style={styles.foodOptionImage}
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.foodOptionText}>AI识别</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.foodOptionItem}
|
||||
onPress={() => {
|
||||
triggerLightHaptic();
|
||||
router.push(`${ROUTES.FOOD_LIBRARY}?mealType=${currentMealType}`);
|
||||
}}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<View style={[styles.foodOptionIcon]}>
|
||||
<Image
|
||||
source={require('@/assets/images/icons/icon-food.png')}
|
||||
style={styles.foodOptionImage}
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.foodOptionText}>食物库</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.foodOptionItem}
|
||||
onPress={() => {
|
||||
triggerLightHaptic();
|
||||
router.push(`${ROUTES.VOICE_RECORD}?mealType=${currentMealType}`);
|
||||
}}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<View style={[styles.foodOptionIcon]}>
|
||||
<Image
|
||||
source={require('@/assets/images/icons/icon-broadcast.png')}
|
||||
style={styles.foodOptionImage}
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.foodOptionText}>一句话记录</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
</TouchableOpacity>
|
||||
);
|
||||
@@ -264,11 +296,6 @@ const styles = StyleSheet.create({
|
||||
fontSize: 14,
|
||||
color: '#192126',
|
||||
},
|
||||
cardRightContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
},
|
||||
cardSubtitle: {
|
||||
fontSize: 10,
|
||||
color: '#9AA3AE',
|
||||
@@ -416,26 +443,53 @@ const styles = StyleSheet.create({
|
||||
mealEmoji: {
|
||||
fontSize: 24,
|
||||
},
|
||||
addButton: {
|
||||
width: 52,
|
||||
height: 26,
|
||||
borderRadius: 16,
|
||||
backgroundColor: '#7b7be2ff',
|
||||
marginLeft: 8,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
elevation: 2,
|
||||
},
|
||||
mealName: {
|
||||
fontSize: 10,
|
||||
color: '#64748B',
|
||||
fontWeight: '600',
|
||||
},
|
||||
// 食物选项样式
|
||||
foodOptionsContainer: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
marginTop: 12,
|
||||
paddingTop: 12,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: '#F1F5F9',
|
||||
gap: 16,
|
||||
},
|
||||
foodOptionItem: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
foodOptionIcon: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 6,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 4,
|
||||
elevation: 4,
|
||||
},
|
||||
foodOptionEmoji: {
|
||||
fontSize: 14,
|
||||
},
|
||||
foodOptionImage: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
foodOptionText: {
|
||||
fontSize: 10,
|
||||
fontWeight: '500',
|
||||
color: '#192126',
|
||||
textAlign: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user