import { useEffect, useState } from 'react'; import { View, Text, FlatList, StyleSheet, Pressable } from 'react-native'; import Animated, { FadeInDown, useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Image } from 'expo-image'; import Svg, { Path } from 'react-native-svg'; import { Colors, Font, Spacing, Radius, TAB_BAR_HEIGHT, MINI_PLAYER_HEIGHT } from '../../constants/theme'; import { getTracks, Track, coverUrl } from '../../services/api'; import { usePlayer, useLikes } from '../../store'; export default function LikedScreen() { const [all, setAll] = useState([]); const insets = useSafeAreaInsets(); const { setQueue } = usePlayer(); const { likes, toggleLike } = useLikes(); useEffect(() => { getTracks().then(setAll); }, []); const liked = all.filter(t => likes.has(t.id)); const playTrack = (track: Track, idx: number) => { setQueue(liked, idx); usePlayer.getState().setExpanded(true); }; return ( Понравилось {liked.length} треков {liked.length === 0 ? ( ♡ Пусто Нажмите ♡ у трека, чтобы добавить его сюда ) : ( String(t.id)} contentContainerStyle={{ paddingHorizontal: Spacing.md, paddingBottom: TAB_BAR_HEIGHT + MINI_PLAYER_HEIGHT + 24 }} showsVerticalScrollIndicator={false} renderItem={({ item, index }) => ( playTrack(item, index)} onUnlike={() => toggleLike(item.id)} /> )} /> )} ); } function LikedRow({ track, index, onPress, onUnlike }: { track: Track; index: number; onPress: () => void; onUnlike: () => void; }) { const { queue, index: qi } = usePlayer(); const active = queue[qi]?.id === track.id; const scale = useSharedValue(1); const aStyle = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }] })); const cover = coverUrl(track.cover_url); return ( { scale.value = withSpring(0.97, { damping: 15 }); }} onPressOut={() => { scale.value = withSpring(1, { damping: 15 }); }} onPress={onPress} style={[styles.row, active && styles.rowActive]} > {track.title} {track.artist} ); } function fmt(s: number) { const m = Math.floor(s / 60), sec = Math.floor(s % 60); return `${m}:${sec < 10 ? '0' : ''}${sec}`; } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: Colors.bg }, header: { flexDirection: 'row', alignItems: 'center', gap: 10, paddingHorizontal: Spacing.md, paddingTop: Spacing.md, paddingBottom: Spacing.md }, title: { color: Colors.text, fontSize: Font.xxl, fontWeight: '800', letterSpacing: -0.5, flex: 1 }, count: { color: Colors.text3, fontSize: Font.sm }, empty: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingBottom: 120 }, emptyIcon: { fontSize: 52, color: Colors.text3, marginBottom: 16 }, emptyTitle: { color: Colors.text, fontSize: Font.lg, fontWeight: '700', marginBottom: 8 }, emptyText: { color: Colors.text2, fontSize: Font.sm, textAlign: 'center', lineHeight: 20 }, row: { flexDirection: 'row', alignItems: 'center', paddingVertical: 10, gap: Spacing.md, borderRadius: Radius.sm }, rowActive: { backgroundColor: Colors.surface + '80' }, cover: { width: 48, height: 48, borderRadius: Radius.sm, backgroundColor: Colors.elevated }, info: { flex: 1 }, trackTitle: { color: Colors.text, fontSize: Font.md, fontWeight: '600' }, artist: { color: Colors.text2, fontSize: Font.sm, marginTop: 2 }, likeBtn: { padding: 4 }, });