feat: 优化 AI 教练聊天和打卡功能

- 在 AI 教练聊天界面中添加会话缓存功能,支持冷启动时恢复聊天记录
- 实现轻量防抖机制,确保会话变动时及时保存缓存
- 在打卡功能中集成按月加载打卡记录,提升用户体验
- 更新 Redux 状态管理,支持打卡记录的按月加载和缓存
- 新增打卡日历页面,允许用户查看每日打卡记录
- 优化样式以适应新功能的展示和交互
This commit is contained in:
richarjiang
2025-08-14 09:57:13 +08:00
parent 7ad26590e5
commit e3e2f1b8c6
18 changed files with 918 additions and 117 deletions

View File

@@ -10,6 +10,7 @@ import { ensureHealthPermissions, fetchHealthDataForDate, fetchTodayHealthData }
import { Ionicons } from '@expo/vector-icons';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
import { useFocusEffect } from '@react-navigation/native';
import { useRouter } from 'expo-router';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import {
SafeAreaView,
@@ -22,6 +23,7 @@ import {
import { useSafeAreaInsets } from 'react-native-safe-area-context';
export default function ExploreScreen() {
const router = useRouter();
const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
const colorTokens = Colors[theme];
const stepGoal = useAppSelector((s) => s.user.profile?.dailyStepsGoal) ?? 2000;
@@ -143,8 +145,13 @@ export default function ExploreScreen() {
})}
</ScrollView>
{/* 今日报告 标题 */}
<Text style={styles.sectionTitle}></Text>
{/* 打卡入口 */}
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 24, marginBottom: 8 }}>
<Text style={styles.sectionTitle}></Text>
<TouchableOpacity onPress={() => router.push('/checkin/calendar')} accessibilityRole="button">
<Text style={{ color: '#6B7280', fontWeight: '700' }}></Text>
</TouchableOpacity>
</View>
{/* 取消卡片内 loading保持静默刷新提升体验 */}

View File

@@ -172,11 +172,12 @@ export default function HomeScreen() {
level="初学者"
progress={0}
/>
<Pressable onPress={() => pushIfAuthedElseLogin('/challenge')}>
{/* 原“每周打卡”改为进入打卡日历 */}
<Pressable onPress={() => router.push('/checkin/calendar')}>
<PlanCard
image={'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/images/Image30play@2x.png'}
title="每周打卡"
subtitle="养成训练习惯,练出好身材"
title="打卡日历"
subtitle="查看每日打卡记录(点亮日期)"
progress={0.75}
/>
</Pressable>

View File

@@ -72,15 +72,26 @@ export default function PersonalScreen() {
useEffect(() => { load(); }, []);
useFocusEffect(React.useCallback(() => {
// 每次聚焦时从后端拉取最新用户资料
// 聚焦时只拉后端,避免与本地 load 循环触发
dispatch(fetchMyProfile());
load();
return () => { };
}, [dispatch]));
useEffect(() => {
if (userProfileFromRedux) {
setProfile(userProfileFromRedux);
}
const r = userProfileFromRedux as any;
if (!r) return;
setProfile((prev) => {
const next = { ...prev } as any;
const nameNext = (r.name && String(r.name)) || prev.name;
const genderNext = (r.gender === 'male' || r.gender === 'female') ? r.gender : (prev.gender ?? '');
const avatarUriNext = typeof r.avatar === 'string' && (r.avatar.startsWith('http') || r.avatar.startsWith('data:'))
? r.avatar
: prev.avatarUri;
let changed = false;
if (next.name !== nameNext) { next.name = nameNext; changed = true; }
if (next.gender !== genderNext) { next.gender = genderNext; changed = true; }
if (next.avatarUri !== avatarUriNext) { next.avatarUri = avatarUriNext; changed = true; }
return changed ? next : prev;
});
}, [userProfileFromRedux]);
const formatHeight = () => {