diff --git a/jukebox/App.js b/jukebox/App.js index b63ff23..8053924 100644 --- a/jukebox/App.js +++ b/jukebox/App.js @@ -3,6 +3,7 @@ import { StyleSheet, Text, View, Pressable } from "react-native"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { createContext, useState, useContext } from "react"; +import { SafeAreaProvider } from "react-native-safe-area-context"; import MediaPlayer from "./src/components/MediaPlayer"; @@ -26,9 +27,7 @@ export function UsePlayer() { } function PlayerProvider({ children }) { - const [currentTrack, setCurrentTrack] = useState({ - title: "Swans - A Piece Of The Sky", - }); + const [currentTrack, setCurrentTrack] = useState(); const [isPlaying, setIsPlaying] = useState(false); @@ -61,7 +60,7 @@ function RootLayout() { const { currentTrack } = UsePlayer(); return ( - + @@ -69,7 +68,7 @@ function RootLayout() { - + ); } diff --git a/jukebox/src/components/MediaPlayer.js b/jukebox/src/components/MediaPlayer.js index 58915d6..97ddb9c 100644 --- a/jukebox/src/components/MediaPlayer.js +++ b/jukebox/src/components/MediaPlayer.js @@ -1,33 +1,38 @@ import { useState } from "react"; -import { TouchableOpacity, Text, StyleSheet } from "react-native"; -import { View } from "react-native-web"; +import { View, Text, StyleSheet } from "react-native"; import { Button, Slider } from "rn-inkpad"; import { LinearGradient } from "expo-linear-gradient"; -export default function MediaPlayer({ title, onPress }) { +export default function MediaPlayer() { const [isPlaying, setIsPlaying] = useState(false); + const [progress, setProgress] = useState(35); return ( - {title} + + PlaceholderArtist - PlaceholderTrack + 1:20 - - 4:08 @@ -57,12 +61,14 @@ export default function MediaPlayer({ title, onPress }) { const styles = StyleSheet.create({ box: { borderRadius: 15, - padding: 20, + paddingHorizontal: 16, + paddingTop: 12, + paddingBottom: 10, alignSelf: "stretch", marginHorizontal: 5, - height: "20%", + minHeight: 120, + justifyContent: "space-between", alignItems: "center", - opacity: 0.98, }, name_album_and_artist: { color: "#ffffff", @@ -70,11 +76,10 @@ const styles = StyleSheet.create({ fontWeight: "bold", }, playback_row: { - flex: 1, flexDirection: "row", width: "100%", alignItems: "center", - marginTop: 15, + marginTop: 10, }, slider_wrapper: { flex: 1, @@ -84,4 +89,4 @@ const styles = StyleSheet.create({ color: "#ffffff", fontWeight: "bold", }, -}); +}); \ No newline at end of file diff --git a/jukebox/src/components/TrackRow.js b/jukebox/src/components/TrackRow.js index 53500f2..8cf43ba 100644 --- a/jukebox/src/components/TrackRow.js +++ b/jukebox/src/components/TrackRow.js @@ -1,5 +1,6 @@ import React from 'react'; import { Pressable, View, Text, StyleSheet, Image } from 'react-native'; +import { Ionicons } from '@expo/vector-icons'; import { durationFormatter } from './DurationFormatter'; export default function TrackRow({ @@ -16,20 +17,22 @@ export default function TrackRow({ {cover ? : null} - - {title} - - - {artist} - + {title} + {artist} - {duration ? {durationFormatter(duration)} : "0"} + {duration ? ( + {durationFormatter(duration)} + ) : ( + 0:00 + )} - - - {liked ? '♥' : '♡'} - + + ); @@ -67,14 +70,9 @@ const styles = StyleSheet.create({ fontSize: 15, paddingHorizontal: 18, }, - heart: { - fontSize: 22, - color: '#fff', - paddingHorizontal: 10, - }, - heartLiked: { - fontSize: 22, - color: '#ff4d6d', - paddingHorizontal: 10, + heartBtn: { + width: 32, + alignItems: 'center', + justifyContent: 'center', }, }); \ No newline at end of file diff --git a/jukebox/src/screens/AlbumScreen.js b/jukebox/src/screens/AlbumScreen.js index bd7148e..0acec5d 100644 --- a/jukebox/src/screens/AlbumScreen.js +++ b/jukebox/src/screens/AlbumScreen.js @@ -1,5 +1,6 @@ import React, { useMemo } from 'react'; import { View, Text, StyleSheet, FlatList, Pressable, Image } from 'react-native'; +import { SafeAreaView } from "react-native-safe-area-context"; import TrackRow from '../components/TrackRow'; import { useLibrary } from '../contexts/LibraryContext'; import { durationFormatter } from '../components/DurationFormatter'; @@ -8,14 +9,13 @@ export default function AlbumScreen({ route, navigation }) { const { album: routeAlbum } = route.params; const { albums, toggleLike } = useLibrary(); - // Always use latest album from context (so likes stay in sync) const album = useMemo( () => albums.find((a) => a.id === routeAlbum.id) ?? routeAlbum, [albums, routeAlbum] ); return ( - + navigation.goBack()} style={styles.backBtn}> ← Back @@ -46,7 +46,7 @@ export default function AlbumScreen({ route, navigation }) { )} contentContainerStyle={styles.trackList} /> - + ); } @@ -54,48 +54,11 @@ const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#000', - paddingTop: 28, paddingHorizontal: 16, paddingBottom: 24, }, - header: { - alignItems: 'center', - }, - cover: { - width: 180, - height: 180, - borderRadius: 8, - marginBottom: 12, - }, - title: { - color: '#fff', - fontSize: 32, - fontWeight: '700', - textAlign: 'center', - marginBottom: 1, - }, - artist: { - color: '#fff', - fontSize: 26, - fontWeight: '500', - textAlign: 'center', - marginTop: 1, - }, - meta: { - color: '#fff', - fontSize: 14, - fontWeight: '500', - textAlign: 'center', - marginTop: 8, - marginBottom: 24, - }, - trackList: { - width: '100%', - paddingHorizontal: 16, - paddingBottom: 180, - }, backBtn: { - marginBottom: 10, + marginBottom: 8, alignSelf: 'flex-start', }, backText: { @@ -103,4 +66,41 @@ const styles = StyleSheet.create({ fontSize: 16, fontWeight: '600', }, + header: { + alignItems: 'center', + marginBottom: 10, + }, + cover: { + width: 140, + height: 140, + borderRadius: 8, + marginBottom: 8, + }, + title: { + color: '#fff', + fontSize: 24, + fontWeight: '700', + textAlign: 'center', + marginBottom: 0, + }, + artist: { + color: '#fff', + fontSize: 18, + fontWeight: '500', + textAlign: 'center', + marginTop: 1, + }, + meta: { + color: '#cfcfcf', + fontSize: 12, + fontWeight: '500', + textAlign: 'center', + marginTop: 6, + marginBottom: 10, + }, + trackList: { + width: '100%', + paddingHorizontal: 4, + paddingBottom: 180, + }, }); \ No newline at end of file diff --git a/jukebox/src/screens/HomeScreen.js b/jukebox/src/screens/HomeScreen.js index 41f114a..37e89b1 100644 --- a/jukebox/src/screens/HomeScreen.js +++ b/jukebox/src/screens/HomeScreen.js @@ -11,6 +11,7 @@ import { Ionicons } from "@expo/vector-icons"; import { useNavigation } from "@react-navigation/native"; import TrackRow from "../components/TrackRow"; import { useLibrary } from "../contexts/LibraryContext"; +import { SafeAreaView } from "react-native-safe-area-context"; export default function HomeScreen() { const navigation = useNavigation(); @@ -19,7 +20,7 @@ export default function HomeScreen() { const homeLikedTracks = useMemo(() => likedTracks.slice(0, 5), [likedTracks]); return ( - + Home @@ -77,7 +78,7 @@ export default function HomeScreen() { )} showsVerticalScrollIndicator={false} /> - + ); } diff --git a/jukebox/src/screens/LikedTracksScreen.js b/jukebox/src/screens/LikedTracksScreen.js index d78c266..aabceb2 100644 --- a/jukebox/src/screens/LikedTracksScreen.js +++ b/jukebox/src/screens/LikedTracksScreen.js @@ -9,6 +9,7 @@ import { } from "react-native"; import TrackRow from "../components/TrackRow"; import { useLibrary } from "../contexts/LibraryContext"; +import { SafeAreaView } from "react-native-safe-area-context"; export default function LikedTracksScreen({ navigation }) { const [query, setQuery] = useState(""); @@ -48,7 +49,7 @@ export default function LikedTracksScreen({ navigation }) { }, [likedTracks, query, sortBy, sortDir]); return ( - + navigation.goBack()} style={styles.backBtn}> ← Back @@ -123,7 +124,7 @@ export default function LikedTracksScreen({ navigation }) { keyboardShouldPersistTaps="handled" contentContainerStyle={{ paddingBottom: 180 }} /> - + ); } diff --git a/jukebox/src/screens/LoginScreen.js b/jukebox/src/screens/LoginScreen.js index 7a8206a..5d86e5c 100644 --- a/jukebox/src/screens/LoginScreen.js +++ b/jukebox/src/screens/LoginScreen.js @@ -1,5 +1,6 @@ import React, { useState } from "react"; import { View, Text, StyleSheet, TextInput, Pressable } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; export default function LoginScreen({ navigation }) { const [email, setEmail] = useState(""); @@ -18,7 +19,7 @@ export default function LoginScreen({ navigation }) { }; return ( - + navigation.goBack()} style={styles.backBtn}> ← Back @@ -55,7 +56,7 @@ export default function LoginScreen({ navigation }) { Sign Up - + ); } diff --git a/jukebox/src/screens/PasswordResetScreen.js b/jukebox/src/screens/PasswordResetScreen.js index 7612e75..dd0c68c 100644 --- a/jukebox/src/screens/PasswordResetScreen.js +++ b/jukebox/src/screens/PasswordResetScreen.js @@ -1,5 +1,6 @@ import React, { useState } from "react"; import { View, Text, StyleSheet, TextInput, Pressable } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; export default function PasswordResetScreen({ navigation }) { const [email, setEmail] = useState(""); @@ -9,7 +10,7 @@ export default function PasswordResetScreen({ navigation }) { }; return ( - + navigation.goBack()} style={styles.backBtn}> ← Back @@ -29,7 +30,7 @@ export default function PasswordResetScreen({ navigation }) { Send email - + ); } diff --git a/jukebox/src/screens/SettingsScreen.js b/jukebox/src/screens/SettingsScreen.js index 4ce8ba2..608d7f1 100644 --- a/jukebox/src/screens/SettingsScreen.js +++ b/jukebox/src/screens/SettingsScreen.js @@ -1,12 +1,13 @@ import React, { useState } from "react"; import { View, Text, StyleSheet, Pressable, Switch } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; export default function SettingsScreen({ navigation }) { const [notificationsEnabled, setNotificationsEnabled] = useState(true); const [highQuality, setHighQuality] = useState(false); return ( - + navigation.goBack()} style={styles.backBtn}> ← Back @@ -32,7 +33,7 @@ export default function SettingsScreen({ navigation }) { > Log out - + ); } diff --git a/jukebox/src/screens/SignUpScreen.js b/jukebox/src/screens/SignUpScreen.js index ac1e613..9fc7cfb 100644 --- a/jukebox/src/screens/SignUpScreen.js +++ b/jukebox/src/screens/SignUpScreen.js @@ -1,5 +1,6 @@ import React, { useState } from "react"; import { View, Text, StyleSheet, TextInput, Pressable } from "react-native"; +import { SafeAreaView } from "react-native-safe-area-context"; export default function SignUpScreen({ navigation }) { const [email, setEmail] = useState(""); @@ -10,7 +11,7 @@ export default function SignUpScreen({ navigation }) { }; return ( - + navigation.goBack()} style={styles.backBtn}> ← Back @@ -48,7 +49,7 @@ export default function SignUpScreen({ navigation }) { Sign Up - + ); }