feat(medications): 简化药品添加流程并优化AI相机交互体验

- 移除药品添加选项底部抽屉,直接跳转至AI识别相机
- 优化AI相机拍摄完成后的按钮交互,展开为"拍照"和"完成"两个按钮
- 添加相机引导提示本地存储,避免重复显示
- 修复相机页面布局跳动问题,固定相机高度
- 为医疗免责声明组件添加触觉反馈错误处理
- 实现活动热力图的国际化支持,包括月份标签和统计文本
This commit is contained in:
richarjiang
2025-11-25 14:09:24 +08:00
parent 3db2d39a58
commit 6f2b7eb45e
5 changed files with 518 additions and 125 deletions

View File

@@ -2,6 +2,7 @@ import { IconSymbol } from '@/components/ui/IconSymbol';
import { Colors } from '@/constants/Colors';
import { useAppSelector } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
import { useI18n } from '@/hooks/useI18n';
import dayjs from 'dayjs';
import React, { useMemo, useState } from 'react';
import { Dimensions, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
@@ -12,6 +13,7 @@ const ActivityHeatMap = () => {
const colorScheme = useColorScheme();
const colors = Colors[colorScheme ?? 'light'];
const [showPopover, setShowPopover] = useState(false);
const { t } = useI18n();
const activityData = useAppSelector(stat => stat.user.activityHistory);
@@ -103,8 +105,20 @@ const ActivityHeatMap = () => {
// 获取月份标签(简化的月份标签系统)
const getMonthLabels = useMemo(() => {
const monthNames = ['1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月'];
const monthNames = [
t('statistics.activityHeatMap.months.1'),
t('statistics.activityHeatMap.months.2'),
t('statistics.activityHeatMap.months.3'),
t('statistics.activityHeatMap.months.4'),
t('statistics.activityHeatMap.months.5'),
t('statistics.activityHeatMap.months.6'),
t('statistics.activityHeatMap.months.7'),
t('statistics.activityHeatMap.months.8'),
t('statistics.activityHeatMap.months.9'),
t('statistics.activityHeatMap.months.10'),
t('statistics.activityHeatMap.months.11'),
t('statistics.activityHeatMap.months.12'),
];
// 简单策略均匀分布4-5个月份标签
const totalWeeks = weeksToShow;
@@ -130,7 +144,7 @@ const ActivityHeatMap = () => {
});
return labelPositions;
}, [organizeDataByWeeks, weeksToShow]);
}, [organizeDataByWeeks, weeksToShow, t]);
// 计算活动统计
const activityStats = useMemo(() => {
@@ -156,14 +170,14 @@ const ActivityHeatMap = () => {
<View style={styles.header}>
<View style={styles.titleRow}>
<Text style={[styles.subtitle, { color: colors.textMuted }]}>
6 {activityStats.activeDays}
{t('statistics.activityHeatMap.subtitle', { days: activityStats.activeDays })}
</Text>
<View style={styles.rightSection}>
<View style={[styles.statsBadge, {
backgroundColor: 'rgba(122, 90, 248, 0.1)'
}]}>
<Text style={[styles.statsText, { color: colors.primary }]}>
{activityStats.activeRate}%
{t('statistics.activityHeatMap.activeRate', { rate: activityStats.activeRate })}
</Text>
</View>
<Popover
@@ -184,23 +198,23 @@ const ActivityHeatMap = () => {
>
<View style={[styles.popoverContent, { backgroundColor: colors.card }]}>
<Text style={[styles.popoverTitle, { color: colors.text }]}>
AI
{t('statistics.activityHeatMap.popover.title')}
</Text>
<Text style={[styles.popoverSubtitle, { color: colors.text }]}>
{t('statistics.activityHeatMap.popover.subtitle')}
</Text>
<View style={styles.popoverList}>
<Text style={[styles.popoverItem, { color: colors.textMuted }]}>
1. +1
{t('statistics.activityHeatMap.popover.rules.login')}
</Text>
<Text style={[styles.popoverItem, { color: colors.textMuted }]}>
2. +1
{t('statistics.activityHeatMap.popover.rules.mood')}
</Text>
<Text style={[styles.popoverItem, { color: colors.textMuted }]}>
3. +1
{t('statistics.activityHeatMap.popover.rules.diet')}
</Text>
<Text style={[styles.popoverItem, { color: colors.textMuted }]}>
4. +1
{t('statistics.activityHeatMap.popover.rules.goal')}
</Text>
</View>
</View>
@@ -263,7 +277,9 @@ const ActivityHeatMap = () => {
{/* 图例 */}
<View style={styles.legend}>
<Text style={[styles.legendText, { color: colors.textMuted }]}></Text>
<Text style={[styles.legendText, { color: colors.textMuted }]}>
{t('statistics.activityHeatMap.legend.less')}
</Text>
<View style={styles.legendColors}>
{[0, 1, 2, 3, 4].map((level) => (
<View
@@ -278,7 +294,9 @@ const ActivityHeatMap = () => {
/>
))}
</View>
<Text style={[styles.legendText, { color: colors.textMuted }]}></Text>
<Text style={[styles.legendText, { color: colors.textMuted }]}>
{t('statistics.activityHeatMap.legend.more')}
</Text>
</View>
</View>
);