import { LinearGradient } from 'expo-linear-gradient'; import React, { useState } from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { StressAnalysisModal } from './StressAnalysisModal'; interface StressMeterProps { value: number | null; updateTime?: Date; style?: any; hrvValue: number; } export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterProps) { // 将HRV值转换为压力指数(0-100) // HRV值范围:30-110ms,映射到压力指数100-0 // HRV值越高,压力越小;HRV值越低,压力越大 // 根据压力指数计算状态 const getStressStatus = () => { if (value === null) { return '未知'; } else if (value >= 70) { return '放松'; } else if (value >= 30) { return '正常'; } else { return '紧张'; } }; // 根据状态获取表情 const getStatusEmoji = () => { // 当HRV值为null或0时,不展示表情 if (value === null || value === 0) { return ''; } const status = getStressStatus(); switch (status) { case '未知': return ''; case '放松': return '😌'; case '正常': return '😊'; case '紧张': return '😰'; default: return '😊'; } }; // 计算进度条位置(0-100%) // 压力指数越高,进度条越满(红色区域越多) const progressPercentage = value !== null ? Math.max(0, Math.min(100, value)) : 0; // 在组件内部添加状态 const [showStressModal, setShowStressModal] = useState(false); // 修改 onPress 处理函数 const handlePress = () => { setShowStressModal(true); }; return ( <> {/* 头部区域 */} 压力 {getStatusEmoji()} {/* 数值显示区域 */} {value === null ? '--' : value} 指数 {/* 进度条区域 */} {/* 渐变背景进度条 */} {/* 白色圆形指示器 */} {/* 更新时间 {updateTime && ( {formatUpdateTime(updateTime)} )} */} {/* 压力分析浮窗 */} setShowStressModal(false)} hrvValue={hrvValue} updateTime={updateTime || new Date()} /> ); } const styles = StyleSheet.create({ container: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 14, marginBottom: 12, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.08, shadowRadius: 8, elevation: 3, position: 'relative', overflow: 'hidden', minHeight: 110, width: 140, }, gradientBackground: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, borderRadius: 16, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, }, leftSection: { flexDirection: 'row', alignItems: 'center', }, iconContainer: { width: 24, height: 24, borderRadius: 6, backgroundColor: '#EBF4FF', alignItems: 'center', justifyContent: 'center', marginRight: 6, }, title: { fontSize: 14, fontWeight: '700', color: '#192126', }, emoji: { fontSize: 16, }, valueSection: { flexDirection: 'row', alignItems: 'baseline', marginBottom: 12, }, value: { fontSize: 28, fontWeight: '800', color: '#192126', lineHeight: 32, }, unit: { fontSize: 12, fontWeight: '500', color: '#9AA3AE', marginLeft: 4, }, progressContainer: { height: 16, marginBottom: 4, }, progressTrack: { height: 8, borderRadius: 4, position: 'relative', overflow: 'visible', }, progressBar: { height: '100%', borderRadius: 4, overflow: 'hidden', }, gradientBar: { height: '100%', borderRadius: 4, }, indicator: { position: 'absolute', top: -4, width: 16, height: 16, borderRadius: 8, backgroundColor: '#FFFFFF', shadowColor: '#000', shadowOffset: { width: 0, height: 1, }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, borderWidth: 1.5, borderColor: '#E5E7EB', }, updateTime: { fontSize: 10, color: '#9AA3AE', textAlign: 'right', marginTop: 2, }, });