Files
mindfulness/client/components/home/FavoritesModal.tsx
2026-01-29 19:09:36 +08:00

90 lines
2.3 KiB
TypeScript

import React, { useEffect, useMemo, useState } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
import { useTranslation } from 'react-i18next';
import SheetModal from '@/components/ui/SheetModal';
import { MOCK_CONTENT } from '@/src/constants/mockContent';
import { getFavorites } from '@/src/storage/appStorage';
type Props = {
visible: boolean;
onClose: () => void;
};
export default function FavoritesModal({ visible, onClose }: Props) {
const { t } = useTranslation();
const [ids, setIds] = useState<string[]>([]);
// 每次打开时刷新一次,确保展示最新“喜欢”
useEffect(() => {
if (!visible) return;
let cancelled = false;
(async () => {
const list = await getFavorites();
if (!cancelled) setIds(list);
})();
return () => {
cancelled = true;
};
}, [visible]);
const items = useMemo(() => {
const map = new Map(MOCK_CONTENT.map((c) => [c.id, c]));
return ids.map((id) => map.get(id)).filter(Boolean) as { id: string; text: string }[];
}, [ids]);
return (
<SheetModal visible={visible} title={t('profile.favorites')} onClose={onClose}>
<View style={styles.container}>
{items.length === 0 ? (
<Text style={styles.empty}>{t('favorites.empty')}</Text>
) : (
<FlatList
data={items}
keyExtractor={(it) => it.id}
contentContainerStyle={styles.list}
renderItem={({ item }) => (
<View style={styles.row}>
<Text style={styles.text}>{item.text}</Text>
</View>
)}
/>
)}
</View>
</SheetModal>
);
}
const styles = StyleSheet.create({
container: {
borderRadius: 16,
backgroundColor: 'rgba(255,255,255,0.75)',
overflow: 'hidden',
marginBottom: 8,
},
empty: {
color: 'rgba(94,42,40,0.55)',
fontSize: 15,
textAlign: 'center',
paddingVertical: 26,
paddingHorizontal: 14,
},
list: {
paddingBottom: 10,
},
row: {
paddingHorizontal: 14,
paddingVertical: 14,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: 'rgba(94,42,40,0.10)',
backgroundColor: 'rgba(255,255,255,0.15)',
},
text: {
color: '#5E2A28',
fontSize: 15,
lineHeight: 22,
fontWeight: '600',
},
});