diff --git a/app.json b/app.json
index 9dc9658..f02f35b 100644
--- a/app.json
+++ b/app.json
@@ -1,58 +1,59 @@
-{
- "expo": {
- "name": "Burmalda Music",
- "slug": "burmalda-music",
- "version": "1.0.0",
- "orientation": "portrait",
- "icon": "./assets/icon.png",
- "userInterfaceStyle": "dark",
- "splash": {
- "image": "./assets/splash.png",
- "resizeMode": "contain",
- "backgroundColor": "#0a0a0a"
- },
- "assetBundlePatterns": ["**/*"],
- "ios": {
- "supportsTablet": false,
- "bundleIdentifier": "space.nodeshift.burmalda",
- "buildNumber": "1",
- "infoPlist": {
- "UIBackgroundModes": ["audio"],
- "NSMicrophoneUsageDescription": "Не используется",
- "CFBundleURLTypes": [
- {
- "CFBundleURLSchemes": ["burmalda"]
- }
- ]
- }
- },
- "scheme": "burmalda",
- "plugins": [
- "expo-router",
- "react-native-track-player",
- [
- "expo-updates",
- {
- "username": "nodeshift"
- }
- ]
- ],
- "updates": {
- "enabled": true,
- "checkAutomatically": "ON_LOAD",
- "url": "https://nodeshift.space/api/ios/updates"
- },
- "runtimeVersion": {
- "policy": "appVersion"
- },
- "extra": {
- "apiBase": "https://music.nodeshift.space",
- "cloudClientId": "nsc_A5zi4cZ103aYJGcNTG1bERXV1YCAQW_U",
- "eas": {}
-
- },
- "experiments": {
- "typedRoutes": true
- }
- }
-}
+{
+ "expo": {
+ "name": "Burmalda Music",
+ "slug": "burmalda-music",
+ "version": "1.0.0",
+ "orientation": "portrait",
+ "icon": "./assets/icon.png",
+ "userInterfaceStyle": "dark",
+ "splash": {
+ "image": "./assets/splash.png",
+ "resizeMode": "contain",
+ "backgroundColor": "#0a0a0a"
+ },
+ "assetBundlePatterns": ["**/*"],
+ "ios": {
+ "supportsTablet": false,
+ "bundleIdentifier": "space.nodeshift.burmalda",
+ "buildNumber": "1",
+ "infoPlist": {
+ "UIBackgroundModes": ["audio"],
+ "NSMicrophoneUsageDescription": "Не используется",
+ "NSFileProtectionComplete": "NSFileProtectionCompleteUnlessOpen",
+ "CFBundleURLTypes": [
+ {
+ "CFBundleURLSchemes": ["burmalda"]
+ }
+ ]
+ }
+ },
+ "scheme": "burmalda",
+ "plugins": [
+ "expo-router",
+ "react-native-track-player",
+ [
+ "expo-updates",
+ {
+ "username": "nodeshift"
+ }
+ ]
+ ],
+ "updates": {
+ "enabled": true,
+ "checkAutomatically": "ON_LOAD",
+ "url": "https://nodeshift.space/api/ios/updates"
+ },
+ "runtimeVersion": {
+ "policy": "appVersion"
+ },
+ "extra": {
+ "apiBase": "https://music.nodeshift.space",
+ "cloudClientId": "nsc_A5zi4cZ103aYJGcNTG1bERXV1YCAQW_U",
+ "eas": {}
+
+ },
+ "experiments": {
+ "typedRoutes": true
+ }
+ }
+}
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index 65f5986..27908b6 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -1,111 +1,111 @@
-import { useEffect } from 'react';
-import { View, StyleSheet, ActivityIndicator } from 'react-native';
-import { Tabs, router } from 'expo-router';
-import { BlurView } from 'expo-blur';
-import Svg, { Path, Circle, Line, Polyline } from 'react-native-svg';
-import { Colors, TAB_BAR_HEIGHT } from '../../constants/theme';
-import { useAuth, usePlayer, useLikes } from '../../store';
-import { useAudio } from '../../hooks/useAudio';
-import MiniPlayer from '../../components/MiniPlayer';
-import Player from '../../components/Player';
-
-export default function TabsLayout() {
- const { user, ready } = useAuth();
- const { expanded } = usePlayer();
- const { loadLikes } = useLikes();
- useAudio(); // single audio controller for the whole app
-
- useEffect(() => {
- if (ready && !user) router.replace('/auth');
- }, [user, ready]);
-
- useEffect(() => {
- if (user) loadLikes();
- }, [user]);
-
- if (!ready) return (
-
-
-
- );
- if (!user) return null;
-
- return (
-
- (
-
- ),
- tabBarActiveTintColor: Colors.text,
- tabBarInactiveTintColor: Colors.text3,
- tabBarLabelStyle: { fontSize: 9, fontWeight: '500', letterSpacing: 0.3, marginBottom: 4 },
- tabBarItemStyle: { paddingTop: 6 },
- }}
- >
- }} />
- }} />
- }} />
- }} />
- }} />
-
-
-
- {expanded && }
-
- );
-}
-
-function HomeIcon({ color }: { color: string }) {
- return (
-
- );
-}
-function LibIcon({ color }: { color: string }) {
- return (
-
- );
-}
-function SearchIcon({ color }: { color: string }) {
- return (
-
- );
-}
-function HeartIcon({ color }: { color: string }) {
- return (
-
- );
-}
-function ProfileIcon({ color }: { color: string }) {
- return (
-
- );
-}
-
-const styles = StyleSheet.create({
- tabBar: {
- position: 'absolute',
- borderTopWidth: StyleSheet.hairlineWidth,
- borderTopColor: 'rgba(255,255,255,0.08)',
- backgroundColor: 'transparent',
- elevation: 0,
- height: TAB_BAR_HEIGHT,
- },
-});
+import { useEffect } from 'react';
+import { View, StyleSheet, ActivityIndicator } from 'react-native';
+import { Tabs, router } from 'expo-router';
+import { BlurView } from 'expo-blur';
+import Svg, { Path, Circle, Line, Polyline } from 'react-native-svg';
+import { Colors, TAB_BAR_HEIGHT } from '../../constants/theme';
+import { useAuth, usePlayer, useLikes } from '../../store';
+import { useAudio } from '../../hooks/useAudio';
+import MiniPlayer from '../../components/MiniPlayer';
+import Player from '../../components/Player';
+
+export default function TabsLayout() {
+ const { user, ready } = useAuth();
+ const { expanded } = usePlayer();
+ const { loadLikes } = useLikes();
+ useAudio(); // single audio controller for the whole app
+
+ useEffect(() => {
+ if (ready && !user) router.replace('/auth');
+ }, [user, ready]);
+
+ useEffect(() => {
+ if (user) loadLikes();
+ }, [user]);
+
+ if (!ready) return (
+
+
+
+ );
+ if (!user) return null;
+
+ return (
+
+ (
+
+ ),
+ tabBarActiveTintColor: Colors.text,
+ tabBarInactiveTintColor: Colors.text3,
+ tabBarLabelStyle: { fontSize: 9, fontWeight: '500', letterSpacing: 0.3, marginBottom: 4 },
+ tabBarItemStyle: { paddingTop: 6 },
+ }}
+ >
+ }} />
+ }} />
+ }} />
+ }} />
+ }} />
+
+
+
+ {expanded && }
+
+ );
+}
+
+function HomeIcon({ color }: { color: string }) {
+ return (
+
+ );
+}
+function LibIcon({ color }: { color: string }) {
+ return (
+
+ );
+}
+function SearchIcon({ color }: { color: string }) {
+ return (
+
+ );
+}
+function HeartIcon({ color }: { color: string }) {
+ return (
+
+ );
+}
+function ProfileIcon({ color }: { color: string }) {
+ return (
+
+ );
+}
+
+const styles = StyleSheet.create({
+ tabBar: {
+ position: 'absolute',
+ borderTopWidth: StyleSheet.hairlineWidth,
+ borderTopColor: 'rgba(255,255,255,0.08)',
+ backgroundColor: 'transparent',
+ elevation: 0,
+ height: TAB_BAR_HEIGHT,
+ },
+});
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
index 2b3305e..d425b73 100644
--- a/app/(tabs)/index.tsx
+++ b/app/(tabs)/index.tsx
@@ -1,211 +1,290 @@
-import { useEffect, useState, useCallback } from 'react';
-import { View, Text, ScrollView, StyleSheet, Pressable, Dimensions, RefreshControl } from 'react-native';
-import Animated, { FadeIn, FadeInDown, useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Svg, { Path } from 'react-native-svg';
-import * as Haptics from 'expo-haptics';
-import { Colors, Font, Spacing, Radius, TAB_BAR_HEIGHT, MINI_PLAYER_HEIGHT } from '../../constants/theme';
-import { getTracks, getAlbums, Track, Album, coverUrl } from '../../services/api';
-import { usePlayer, useLikes } from '../../store';
-import CoverImage from '../../components/CoverImage';
-
-const { width } = Dimensions.get('window');
-const CARD_W = (width - Spacing.md * 3) / 2;
-
-export default function HomeScreen() {
- const [tracks, setTracks] = useState