diff --git a/App.tsx b/App.tsx index 5029abe..9e52df4 100644 --- a/App.tsx +++ b/App.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { NavigationContainer } from '@react-navigation/native'; +import { DarkTheme, NavigationContainer } from '@react-navigation/native'; import SplashPage from './src/components/SplashPage'; import RootNavigator from './src/components/navigation/RootNavigator'; import { Provider } from 'jotai'; @@ -7,7 +7,7 @@ import { Provider } from 'jotai'; const App = () => ( - + diff --git a/res/arrow_left-fill.png b/res/arrow_left-fill.png new file mode 100644 index 0000000..16aa6e5 Binary files /dev/null and b/res/arrow_left-fill.png differ diff --git a/src/components/common/AlbumView.tsx b/src/components/common/AlbumView.tsx new file mode 100644 index 0000000..0f32c44 --- /dev/null +++ b/src/components/common/AlbumView.tsx @@ -0,0 +1,40 @@ +import { useNavigation } from '@react-navigation/native'; +import { useAtomValue } from 'jotai/utils'; +import React, { useEffect } from 'react'; +import { View, Text } from 'react-native'; +import { albumAtomFamily } from '../../state/music'; +import TopTabContainer from './TopTabContainer'; + +const AlbumDetails: React.FC<{ + id: string, +}> = ({ id }) => { + const navigation = useNavigation(); + const album = useAtomValue(albumAtomFamily(id)); + + useEffect(() => { + if (!album) { + return; + } + navigation.setOptions({ title: album.name }); + }); + + return ( + <> + Name: {album?.name} + Artist: {album?.artist} + + ); +} + +const AlbumView: React.FC<{ + id: string, +}> = ({ id }) => ( + + {id} + Loading...}> + + + +); + +export default React.memo(AlbumView); diff --git a/src/components/common/TopTabBar.tsx b/src/components/common/TopTabBar.tsx deleted file mode 100644 index be3bb97..0000000 --- a/src/components/common/TopTabBar.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { Text, View } from 'react-native'; -import { MaterialTopTabBarProps } from '@react-navigation/material-top-tabs'; -import colors from '../../styles/colors'; -import textStyles from '../../styles/text'; - -const TopTabBar: React.FC = ({ state, descriptors }) => { - return ( - - {state.routes.map((route, index) => { - const { options } = descriptors[route.key]; - const label = - options.tabBarLabel !== undefined - ? options.tabBarLabel - : options.title !== undefined - ? options.title - : route.name; - - const isFocused = state.index === index; - const color = isFocused ? colors.text.primary : colors.text.secondary; - const borderBottomColor = isFocused ? colors.accent : colors.gradient.high; - - return ( - - {label} - - ); - })} - - ); -} - -export default TopTabBar; diff --git a/src/components/library/AlbumsTab.tsx b/src/components/library/AlbumsTab.tsx index 436e504..462a287 100644 --- a/src/components/library/AlbumsTab.tsx +++ b/src/components/library/AlbumsTab.tsx @@ -1,6 +1,7 @@ +import { useNavigation } from '@react-navigation/native'; import { useAtomValue } from 'jotai/utils'; import React, { useEffect } from 'react'; -import { FlatList, Text, View } from 'react-native'; +import { FlatList, Pressable, Text, View } from 'react-native'; import FastImage from 'react-native-fast-image'; import LinearGradient from 'react-native-linear-gradient'; import { Album } from '../../models/music'; @@ -42,18 +43,24 @@ const AlbumArt: React.FC<{ const MemoAlbumArt = React.memo(AlbumArt); const AlbumItem: React.FC<{ + id: string; name: string, artist?: string, coverArtUri?: string -} > = ({ name, artist, coverArtUri }) => { +} > = ({ id, name, artist, coverArtUri }) => { + const navigation = useNavigation(); + const size = 125; return ( - + navigation.navigate('AlbumView', { id })} + > - + ); } const MemoAlbumItem = React.memo(AlbumItem); const AlbumListRenderItem: React.FC<{ item: Album }> = ({ item }) => ( - + ); const AlbumsList = () => { diff --git a/src/components/navigation/LibraryTopTabNavigator.tsx b/src/components/navigation/LibraryTopTabNavigator.tsx index 129252d..4daa161 100644 --- a/src/components/navigation/LibraryTopTabNavigator.tsx +++ b/src/components/navigation/LibraryTopTabNavigator.tsx @@ -4,29 +4,104 @@ import { createMaterialTopTabNavigator } from '@react-navigation/material-top-ta import AlbumsTab from '../library/AlbumsTab'; import ArtistsTab from '../library/ArtistsTab'; import PlaylistsTab from '../library/PlaylistsTab'; -import TopTabBar from '../common/TopTabBar'; +import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack'; +import AlbumView from '../common/AlbumView'; +import { RouteProp } from '@react-navigation/native'; +import text from '../../styles/text'; +import colors from '../../styles/colors'; +import FastImage from 'react-native-fast-image'; const Tab = createMaterialTopTabNavigator(); const LibraryTopTabNavigator = () => ( - - - + + + +); + +type LibraryStackParamList = { + LibraryTopTabs: undefined, + AlbumView: { id: string }; +} + +type AlbumScreenNavigationProp = StackNavigationProp; +type AlbumScreenRouteProp = RouteProp; +type AlbumScreenProps = { + route: AlbumScreenRouteProp, + navigation: AlbumScreenNavigationProp, +}; + +const AlbumScreen: React.FC = ({ route }) => ( + +); + +const Stack = createStackNavigator(); + +const LibraryStackNavigator = () => ( + + + - , + }} /> - - + ); -export default LibraryTopTabNavigator; +export default LibraryStackNavigator; diff --git a/src/state/music.ts b/src/state/music.ts index fd513d1..fd0a841 100644 --- a/src/state/music.ts +++ b/src/state/music.ts @@ -1,5 +1,5 @@ import { atom, useAtom } from 'jotai'; -import { useAtomValue, useUpdateAtom } from 'jotai/utils'; +import { atomFamily, useAtomValue, useUpdateAtom } from 'jotai/utils'; import { Album, Artist } from '../models/music'; import { SubsonicApiClient } from '../subsonic/api'; import { activeServerAtom } from './settings'; @@ -70,3 +70,19 @@ export const useUpdateAlbums = () => { setUpdating(false); } } + +export const albumAtomFamily = atomFamily((id: string) => atom(async (get) => { + const server = get(activeServerAtom); + if (!server) { + return undefined; + } + + const client = new SubsonicApiClient(server); + const response = await client.getAlbum({ id }); + + return { + id, + name: response.data.album.name, + artist: response.data.album.artist, + }; +})); diff --git a/src/styles/text.ts b/src/styles/text.ts index 3d6a363..bb071a8 100644 --- a/src/styles/text.ts +++ b/src/styles/text.ts @@ -12,7 +12,7 @@ const paragraph: TextStyle = { const header: TextStyle = { ...paragraph, - fontSize: 20, + fontSize: 19, fontFamily: fontSemiBold, };