feat(ui): 更新应用品牌名称为 Out Live 并优化睡眠详情页默认数据展示

- 将 Sealife 更名为 Out Live(登录页、隐私弹窗)
- 睡眠详情页无数据时显示 "--" 替代固定默认值
- 移除睡眠阶段卡片中的质量标签与总览徽章
- 修复体重历史卡片依赖监听字段与跳转路由
- 调整喝水提醒后台任务时间范围为 8-21 点
- 标签栏按钮新增 activeOpacity=1 禁用点击透明度变化
This commit is contained in:
richarjiang
2025-09-12 09:59:01 +08:00
parent 1af0945a2f
commit a84c026599
7 changed files with 20 additions and 29 deletions

View File

@@ -61,6 +61,7 @@ export default function TabLayout() {
<TouchableOpacity <TouchableOpacity
onPress={handlePress} onPress={handlePress}
accessibilityRole="button" accessibilityRole="button"
activeOpacity={1}
style={{ style={{
flex: 1, flex: 1,
alignItems: 'center', alignItems: 'center',

View File

@@ -223,8 +223,8 @@ export default function LoginScreen() {
<ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false}> <ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false}>
<View style={styles.headerWrap}> <View style={styles.headerWrap}>
<ThemedText style={[styles.title, { color: color.text }]}>Sealife</ThemedText> <ThemedText style={[styles.title, { color: color.text }]}>Out Live</ThemedText>
<ThemedText style={[styles.subtitle, { color: color.textMuted }]}>Sealife</ThemedText> <ThemedText style={[styles.subtitle, { color: color.textMuted }]}>Out Live</ThemedText>
</View> </View>
{/* Apple 登录 */} {/* Apple 登录 */}

View File

@@ -1,3 +1,4 @@
import { ThemedView } from '@/components/ThemedView';
import { import {
fetchCompleteSleepData, fetchCompleteSleepData,
formatSleepTime, formatSleepTime,
@@ -18,7 +19,6 @@ import {
TouchableOpacity, TouchableOpacity,
View View
} from 'react-native'; } from 'react-native';
import { ThemedView } from '@/components/ThemedView';
import { InfoModal, type SleepDetailData } from '@/components/sleep/InfoModal'; import { InfoModal, type SleepDetailData } from '@/components/sleep/InfoModal';
import { SleepStagesInfoModal } from '@/components/sleep/SleepStagesInfoModal'; import { SleepStagesInfoModal } from '@/components/sleep/SleepStagesInfoModal';
@@ -38,7 +38,7 @@ export default function SleepDetailScreen() {
const colorTokens = Colors[theme]; const colorTokens = Colors[theme];
const [sleepData, setSleepData] = useState<CompleteSleepData | null>(null); const [sleepData, setSleepData] = useState<CompleteSleepData | null>(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
// 从导航参数获取日期,如果没有则使用今天 // 从导航参数获取日期,如果没有则使用今天
const { date: dateParam } = useLocalSearchParams<{ date?: string }>(); const { date: dateParam } = useLocalSearchParams<{ date?: string }>();
const [selectedDate] = useState(() => { const [selectedDate] = useState(() => {
@@ -162,11 +162,9 @@ export default function SleepDetailScreen() {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<Text style={[styles.newStatValue, { color: colorTokens.text }]}> <Text style={[styles.newStatValue, { color: colorTokens.text }]}>
{displayData.totalSleepTime > 0 ? formatSleepTime(displayData.totalSleepTime) : '7h 23m'} {displayData.totalSleepTime > 0 ? formatSleepTime(displayData.totalSleepTime) : '--'}
</Text> </Text>
<View style={[styles.qualityBadge, styles.goodQualityBadge]}>
<Text style={[styles.qualityBadgeText, styles.goodQualityText]}> </Text>
</View>
</View> </View>
<View style={[styles.newStatCard, { backgroundColor: colorTokens.background }]}> <View style={[styles.newStatCard, { backgroundColor: colorTokens.background }]}>
@@ -189,11 +187,8 @@ export default function SleepDetailScreen() {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<Text style={[styles.newStatValue, { color: colorTokens.text }]}> <Text style={[styles.newStatValue, { color: colorTokens.text }]}>
{displayData.sleepQualityPercentage > 0 ? `${displayData.sleepQualityPercentage}%` : '94%'} {displayData.sleepQualityPercentage > 0 ? `${displayData.sleepQualityPercentage}%` : '--%'}
</Text> </Text>
<View style={[styles.qualityBadge, styles.excellentQualityBadge]}>
<Text style={[styles.qualityBadgeText, styles.excellentQualityText]}> </Text>
</View>
</View> </View>
</View> </View>
@@ -228,10 +223,10 @@ export default function SleepDetailScreen() {
} else { } else {
// 使用默认数据 // 使用默认数据
stagesToDisplay = [ stagesToDisplay = [
{ stage: SleepStage.Awake, duration: 3, percentage: 1, quality: 'good' as any }, { stage: SleepStage.Awake, duration: 0, percentage: 0, quality: 'good' as any },
{ stage: SleepStage.REM, duration: 89, percentage: 20, quality: 'good' as any }, { stage: SleepStage.REM, duration: 0, percentage: 0, quality: 'good' as any },
{ stage: SleepStage.Core, duration: 295, percentage: 67, quality: 'good' as any }, { stage: SleepStage.Core, duration: 0, percentage: 0, quality: 'good' as any },
{ stage: SleepStage.Deep, duration: 51, percentage: 12, quality: 'poor' as any } { stage: SleepStage.Deep, duration: 0, percentage: 0, quality: 'poor' as any }
]; ];
} }
return stagesToDisplay; return stagesToDisplay;
@@ -269,11 +264,6 @@ export default function SleepDetailScreen() {
<Text style={[styles.stageCardPercentage, { color: colorTokens.textSecondary }]}> <Text style={[styles.stageCardPercentage, { color: colorTokens.textSecondary }]}>
{stageData.percentage}% {stageData.percentage}%
</Text> </Text>
<View style={[styles.stageCardQuality, { backgroundColor: qualityInfo.bgColor }]}>
<Text style={[styles.stageCardQualityText, { color: qualityInfo.color }]}>
{qualityInfo.text}
</Text>
</View>
</View> </View>
); );
})} })}

View File

@@ -40,7 +40,7 @@ export default function PrivacyConsentModal({
> >
<View style={styles.overlay}> <View style={styles.overlay}>
<View style={styles.container}> <View style={styles.container}>
<Text style={styles.title}>Sealife</Text> <Text style={styles.title}>Out Live</Text>
<View style={styles.contentContainer}> <View style={styles.contentContainer}>
<Text style={styles.description}> <Text style={styles.description}>

View File

@@ -67,7 +67,7 @@ export function WeightHistoryCard() {
if (hasWeight) { if (hasWeight) {
loadWeightHistory(); loadWeightHistory();
} }
}, [hasWeight]); }, [userProfile?.weight]);
const loadWeightHistory = async () => { const loadWeightHistory = async () => {
try { try {
@@ -78,7 +78,7 @@ export function WeightHistoryCard() {
}; };
const navigateToCoach = () => { const navigateToCoach = () => {
pushIfAuthedElseLogin(ROUTES.TAB_COACH); pushIfAuthedElseLogin(ROUTES.WEIGHT_RECORDS);
}; };
const handleShowBMIModal = () => { const handleShowBMIModal = () => {

View File

@@ -3018,9 +3018,9 @@ PODS:
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- SocketRocket - SocketRocket
- Yoga - Yoga
- SDWebImage (5.21.1): - SDWebImage (5.21.2):
- SDWebImage/Core (= 5.21.1) - SDWebImage/Core (= 5.21.2)
- SDWebImage/Core (5.21.1) - SDWebImage/Core (5.21.2)
- SDWebImageAVIFCoder (0.11.0): - SDWebImageAVIFCoder (0.11.0):
- libavif/core (>= 0.11.0) - libavif/core (>= 0.11.0)
- SDWebImage (~> 5.10) - SDWebImage (~> 5.10)
@@ -3539,7 +3539,7 @@ SPEC CHECKSUMS:
RNSentry: f2c39f1113e22413c9bb6e3faa6b27f110d95eaf RNSentry: f2c39f1113e22413c9bb6e3faa6b27f110d95eaf
RNSVG: 6f39605a4c4d200b11435c35bd077553c6b5963a RNSVG: 6f39605a4c4d200b11435c35bd077553c6b5963a
RNWorklets: ad0606bee2a8103c14adb412149789c60b72bfb2 RNWorklets: ad0606bee2a8103c14adb412149789c60b72bfb2
SDWebImage: f29024626962457f3470184232766516dee8dfea SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
SDWebImageAVIFCoder: 00310d246aab3232ce77f1d8f0076f8c4b021d90 SDWebImageAVIFCoder: 00310d246aab3232ce77f1d8f0076f8c4b021d90
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380

View File

@@ -40,7 +40,7 @@ async function executeWaterReminderTask(): Promise<void> {
// 检查时间限制(避免深夜打扰) // 检查时间限制(避免深夜打扰)
const currentHour = new Date().getHours(); const currentHour = new Date().getHours();
if (currentHour < 9 || currentHour >= 21) { if (currentHour < 8 || currentHour >= 21) {
console.log(`当前时间${currentHour}点,不在提醒时间范围内,跳过喝水提醒`); console.log(`当前时间${currentHour}点,不在提醒时间范围内,跳过喝水提醒`);
return; return;
} }