feat(medications): 简化药品添加流程并优化AI相机交互体验
- 移除药品添加选项底部抽屉,直接跳转至AI识别相机 - 优化AI相机拍摄完成后的按钮交互,展开为"拍照"和"完成"两个按钮 - 添加相机引导提示本地存储,避免重复显示 - 修复相机页面布局跳动问题,固定相机高度 - 为医疗免责声明组件添加触觉反馈错误处理 - 实现活动热力图的国际化支持,包括月份标签和统计文本
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -88,13 +88,19 @@ export function MedicalDisclaimerSheet({
|
||||
}, [visible, modalVisible, backdropOpacity, translateY]);
|
||||
|
||||
const handleCancel = () => {
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||
// 安全地执行触觉反馈,避免因触觉反馈失败导致页面卡顿
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light).catch((error) => {
|
||||
console.warn('[MEDICATION] Haptic feedback failed:', error);
|
||||
});
|
||||
onClose();
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (loading) return;
|
||||
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
|
||||
// 安全地执行触觉反馈,避免因触觉反馈失败导致页面卡顿
|
||||
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success).catch((error) => {
|
||||
console.warn('[MEDICATION] Haptic feedback failed:', error);
|
||||
});
|
||||
onConfirm();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user