feat: 更新心情记录功能及相关组件
- 在心情日历中新增心情圆环展示,显示心情强度 - 修改心情记录编辑页面,支持使用图标替代表情 - 优化心情类型配置,使用图片资源替代原有表情 - 新增多种心情图标,丰富用户选择 - 更新相关样式,提升用户体验和界面美观性 - 更新文档,详细描述新功能和使用方法
This commit is contained in:
@@ -3,8 +3,9 @@ import { Colors } from '@/constants/Colors';
|
||||
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { useMoodData } from '@/hooks/useMoodData';
|
||||
import { getMoodOptions } from '@/services/moodCheckins';
|
||||
import { getMoodOptions, MoodOption } from '@/services/moodCheckins';
|
||||
import { selectLatestMoodRecordByDate } from '@/store/moodSlice';
|
||||
import { Image } from 'react-native';
|
||||
import dayjs from 'dayjs';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { router, useFocusEffect, useLocalSearchParams } from 'expo-router';
|
||||
@@ -181,7 +182,7 @@ export default function MoodCalendarScreen() {
|
||||
});
|
||||
};
|
||||
|
||||
const renderMoodIcon = (day: number | null, isSelected: boolean) => {
|
||||
const renderMoodRing = (day: number | null, isSelected: boolean) => {
|
||||
if (!day) return null;
|
||||
|
||||
// 检查该日期是否有心情记录 - 现在从 Redux store 中获取
|
||||
@@ -189,20 +190,40 @@ export default function MoodCalendarScreen() {
|
||||
const dayRecords = moodRecords[dayDateString] || [];
|
||||
const moodRecord = dayRecords.length > 0 ? dayRecords[0] : null;
|
||||
|
||||
const isToday = day === new Date().getDate() &&
|
||||
month === new Date().getMonth() + 1 &&
|
||||
year === new Date().getFullYear();
|
||||
|
||||
if (moodRecord) {
|
||||
const mood = moodOptions.find(m => m.type === moodRecord.moodType);
|
||||
const intensity = moodRecord.intensity;
|
||||
const color = mood?.color || '#7a5af8';
|
||||
|
||||
// 计算圆环的填充比例 (0-1)
|
||||
const fillRatio = intensity / 10;
|
||||
|
||||
return (
|
||||
<View style={[styles.moodIconContainer, { backgroundColor: mood?.color }]}>
|
||||
<View style={styles.moodIcon}>
|
||||
<Text style={styles.moodEmoji}>{mood?.emoji || '😊'}</Text>
|
||||
<View style={isToday ? styles.todayMoodRingContainer : styles.moodRingContainer}>
|
||||
<View style={[isToday ? styles.todayMoodRing : styles.moodRing, { borderColor: color }]}>
|
||||
<View style={[
|
||||
styles.moodRingFill,
|
||||
{
|
||||
backgroundColor: color,
|
||||
height: `${fillRatio * 100}%`,
|
||||
opacity: 0.7,
|
||||
}
|
||||
]} />
|
||||
<Text style={[styles.moodIntensityText, { color: '#fff', fontSize: isToday ? 7 : 8 }]}>
|
||||
{intensity}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.defaultMoodIcon}>
|
||||
<Text style={styles.defaultMoodEmoji}>😊</Text>
|
||||
<View style={isToday ? styles.todayDefaultMoodRing : styles.defaultMoodRing}>
|
||||
<View style={isToday ? styles.todayDefaultMoodRingBorder : styles.defaultMoodRingBorder} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -285,7 +306,7 @@ export default function MoodCalendarScreen() {
|
||||
]}>
|
||||
{day.toString().padStart(2, '0')}
|
||||
</Text>
|
||||
{renderMoodIcon(day, isSelected)}
|
||||
{renderMoodRing(day, isSelected)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
@@ -318,9 +339,10 @@ export default function MoodCalendarScreen() {
|
||||
>
|
||||
<View style={styles.recordIcon}>
|
||||
<View style={styles.moodIcon}>
|
||||
<Text style={styles.moodEmoji}>
|
||||
{moodOptions.find(m => m.type === selectedDateMood.moodType)?.emoji || '😊'}
|
||||
</Text>
|
||||
<Image
|
||||
source={moodOptions.find(m => m.type === selectedDateMood.moodType)?.image}
|
||||
style={styles.moodIconImage}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.recordContent}>
|
||||
@@ -524,8 +546,10 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
moodEmoji: {
|
||||
fontSize: 11,
|
||||
moodIconImage: {
|
||||
width: 18,
|
||||
height: 18,
|
||||
borderRadius: 9,
|
||||
},
|
||||
defaultMoodIcon: {
|
||||
position: 'absolute',
|
||||
@@ -545,6 +569,104 @@ const styles = StyleSheet.create({
|
||||
opacity: 0.4,
|
||||
color: '#7a5af8',
|
||||
},
|
||||
moodRingContainer: {
|
||||
position: 'absolute',
|
||||
bottom: 2,
|
||||
width: 22,
|
||||
height: 22,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
moodRing: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
borderWidth: 1.5,
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: 'rgba(255,255,255,0.95)',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
elevation: 1,
|
||||
},
|
||||
moodRingFill: {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
borderBottomLeftRadius: 8,
|
||||
borderBottomRightRadius: 8,
|
||||
},
|
||||
moodIntensityText: {
|
||||
fontSize: 8,
|
||||
fontWeight: '800',
|
||||
textAlign: 'center',
|
||||
position: 'absolute',
|
||||
zIndex: 1,
|
||||
textShadowColor: 'rgba(0,0,0,0.3)',
|
||||
textShadowOffset: { width: 0, height: 0.5 },
|
||||
textShadowRadius: 1,
|
||||
},
|
||||
defaultMoodRing: {
|
||||
position: 'absolute',
|
||||
bottom: 2,
|
||||
width: 22,
|
||||
height: 22,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
defaultMoodRingBorder: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
borderWidth: 1.5,
|
||||
borderColor: 'rgba(122,90,248,0.3)',
|
||||
borderStyle: 'dashed',
|
||||
backgroundColor: 'rgba(122,90,248,0.05)',
|
||||
},
|
||||
todayMoodRingContainer: {
|
||||
position: 'absolute',
|
||||
bottom: 1,
|
||||
width: 20,
|
||||
height: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
todayMoodRing: {
|
||||
width: 18,
|
||||
height: 18,
|
||||
borderRadius: 9,
|
||||
borderWidth: 1.5,
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: 'rgba(255,255,255,0.95)',
|
||||
shadowColor: '#7a5af8',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
},
|
||||
todayDefaultMoodRing: {
|
||||
position: 'absolute',
|
||||
bottom: 1,
|
||||
width: 20,
|
||||
height: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
todayDefaultMoodRingBorder: {
|
||||
width: 18,
|
||||
height: 18,
|
||||
borderRadius: 9,
|
||||
borderWidth: 1.5,
|
||||
borderColor: 'rgba(122,90,248,0.4)',
|
||||
borderStyle: 'dashed',
|
||||
backgroundColor: 'rgba(122,90,248,0.08)',
|
||||
},
|
||||
selectedDateSection: {
|
||||
backgroundColor: 'rgba(255,255,255,0.95)',
|
||||
margin: 16,
|
||||
|
||||
Reference in New Issue
Block a user