feat: 更新应用名称为“Out Live”,删除推送通知使用指南和喝水记录API修复测试文档,优化饮水设置页面,添加登录状态检查

This commit is contained in:
2025-09-07 10:03:37 +08:00
parent 2e7daae519
commit aaa34a7a07
13 changed files with 105 additions and 550 deletions

View File

@@ -15,7 +15,7 @@ import { useAuthGuard } from '@/hooks/useAuthGuard';
import { selectHealthDataByDate, setHealthData } from '@/store/healthSlice';
import { fetchDailyMoodCheckins, selectLatestMoodRecordByDate } from '@/store/moodSlice';
import { fetchDailyNutritionData, selectNutritionSummaryByDate } from '@/store/nutritionSlice';
import { fetchTodayWaterStats, selectTodayStats } from '@/store/waterSlice';
import { fetchTodayWaterStats } from '@/store/waterSlice';
import { getMonthDaysZh, getTodayIndexInMonth } from '@/utils/date';
import { ensureHealthPermissions, fetchHealthDataForDate, testHRVDataFetch } from '@/utils/health';
import { getTestHealthData } from '@/utils/mockHealthData';
@@ -89,8 +89,6 @@ export default function ExploreScreen() {
// 从 Redux 获取指定日期的健康数据
const healthData = useAppSelector(selectHealthDataByDate(currentSelectedDateString));
// 获取今日喝水统计数据
const todayWaterStats = useAppSelector(selectTodayStats);
// 解构健康数据支持mock数据
const mockData = useMockData ? getTestHealthData('mock') : null;
@@ -101,7 +99,7 @@ export default function ExploreScreen() {
const sleepDuration = useMockData ? (mockData?.sleepDuration ?? null) : (healthData?.sleepDuration ?? null);
const hrvValue = useMockData ? (mockData?.hrv ?? 0) : (healthData?.hrv ?? 0);
const oxygenSaturation = useMockData ? (mockData?.oxygenSaturation ?? null) : (healthData?.oxygenSaturation ?? null);
const heartRate = useMockData ? (mockData?.heartRate ?? null) : (healthData?.heartRate ?? null);
const fitnessRingsData = useMockData ? {
activeCalories: mockData?.activeCalories ?? 0,
activeCaloriesGoal: mockData?.activeCaloriesGoal ?? 350,
@@ -455,7 +453,7 @@ export default function ExploreScreen() {
{/* 右边文字区域 */}
<View style={styles.headerTextContainer}>
<Text style={styles.headerTitle}></Text>
<Text style={styles.headerTitle}>Out Live</Text>
</View>
{/* 开发环境调试按钮 */}

View File

@@ -1,10 +1,12 @@
import { Colors } from '@/constants/Colors';
import { useAuthGuard } from '@/hooks/useAuthGuard';
import { useColorScheme } from '@/hooks/useColorScheme';
import { useWaterDataByDate } from '@/hooks/useWaterData';
import { getQuickWaterAmount, setQuickWaterAmount } from '@/utils/userPreferences';
import { Ionicons } from '@expo/vector-icons';
import { Picker } from '@react-native-picker/picker';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { router, useLocalSearchParams } from 'expo-router';
import React, { useEffect, useState } from 'react';
import {
@@ -32,6 +34,7 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
const { selectedDate } = useLocalSearchParams<{ selectedDate?: string }>();
const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
const colorTokens = Colors[theme];
const { ensureLoggedIn } = useAuthGuard();
const [dailyGoal, setDailyGoal] = useState<string>('2000');
const [quickAddAmount, setQuickAddAmount] = useState<string>('250');
@@ -47,6 +50,19 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
// 使用新的 hook 来处理指定日期的饮水数据
const { waterRecords, dailyWaterGoal, updateWaterGoal, removeWaterRecord } = useWaterDataByDate(selectedDate);
// 检查登录状态
useEffect(() => {
const checkLoginStatus = async () => {
const isLoggedIn = await ensureLoggedIn();
if (!isLoggedIn) {
// 如果未登录,用户会被重定向到登录页面
return;
}
};
checkLoginStatus();
}, [ensureLoggedIn]);
const goalPresets = [1500, 2000, 2500, 3000, 3500, 4000];
const quickAddPresets = [100, 150, 200, 250, 300, 350, 400, 500];
@@ -203,7 +219,19 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
};
return (
<View style={[styles.container, { backgroundColor: colorTokens.background }]}>
<View style={styles.container}>
{/* 背景渐变 */}
<LinearGradient
colors={['#f5e5fbff', '#e5fcfeff', '#eefdffff', '#e6f6fcff']}
style={styles.gradientBackground}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 1 }}
/>
{/* 装饰性圆圈 */}
<View style={styles.decorativeCircle1} />
<View style={styles.decorativeCircle2} />
<HeaderBar
title="饮水设置"
onBack={() => {
@@ -249,7 +277,7 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
<View style={styles.settingLeft}>
<Text style={[styles.settingTitle, { color: colorTokens.text }]}></Text>
<Text style={[styles.settingSubtitle, { color: colorTokens.textSecondary }]}>
"+"
{`设置点击右上角"+"按钮时添加的默认饮水量`}
</Text>
<Text style={[styles.settingValue, { color: colorTokens.textSecondary }]}>{quickAddAmount}ml</Text>
</View>
@@ -382,6 +410,33 @@ const styles = StyleSheet.create({
container: {
flex: 1,
},
gradientBackground: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
},
decorativeCircle1: {
position: 'absolute',
top: 40,
right: 20,
width: 60,
height: 60,
borderRadius: 30,
backgroundColor: '#0EA5E9',
opacity: 0.1,
},
decorativeCircle2: {
position: 'absolute',
bottom: -15,
left: -15,
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#0EA5E9',
opacity: 0.05,
},
keyboardAvoidingView: {
flex: 1,
},
@@ -395,19 +450,19 @@ const styles = StyleSheet.create({
marginBottom: 32,
},
sectionTitle: {
fontSize: 20,
fontWeight: '600',
fontSize: 16,
fontWeight: '500',
marginBottom: 20,
letterSpacing: -0.5,
},
subsectionTitle: {
fontSize: 16,
fontSize: 14,
fontWeight: '500',
marginBottom: 12,
letterSpacing: -0.3,
},
sectionSubtitle: {
fontSize: 14,
fontSize: 12,
fontWeight: '400',
lineHeight: 18,
},
@@ -582,15 +637,18 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 40,
gap: 12,
gap: 16,
},
noRecordsText: {
fontSize: 16,
fontWeight: '600',
fontSize: 15,
fontWeight: '500',
lineHeight: 20,
},
noRecordsSubText: {
fontSize: 14,
fontSize: 13,
textAlign: 'center',
lineHeight: 18,
opacity: 0.7,
},
modalBackdrop: {
...StyleSheet.absoluteFillObject,