mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 23:02:43 +01:00
better tabs and more layout
This commit is contained in:
@@ -29,7 +29,7 @@ const List = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const ArtistsList = () => {
|
||||
const ListPlusControls = () => {
|
||||
const resetArtists = useResetRecoilState(artistsState);
|
||||
const updateArtists = useUpdateArtists();
|
||||
|
||||
@@ -43,11 +43,17 @@ const ArtistsList = () => {
|
||||
title='Update from API'
|
||||
onPress={updateArtists}
|
||||
/>
|
||||
<React.Suspense fallback={<Text>Loading...</Text>}>
|
||||
<List />
|
||||
</React.Suspense>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ArtistsList = () => (
|
||||
<View>
|
||||
<React.Suspense fallback={<Text>Loading...</Text>}>
|
||||
<ListPlusControls />
|
||||
</React.Suspense>
|
||||
</View>
|
||||
)
|
||||
|
||||
export default ArtistsList;
|
||||
|
||||
25
src/components/FocusableIcon.tsx
Normal file
25
src/components/FocusableIcon.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { Image, ImageSourcePropType } from 'react-native';
|
||||
|
||||
export type FocusableIconProps = {
|
||||
focused: boolean,
|
||||
source: ImageSourcePropType;
|
||||
focusedSource?: ImageSourcePropType;
|
||||
width?: number;
|
||||
height?: number;
|
||||
};
|
||||
|
||||
const FocusableIcon: React.FC<FocusableIconProps> = (props) => {
|
||||
props.focusedSource = props.focusedSource || props.source;
|
||||
props.width = props.width || 32;
|
||||
props.height = props.height || 32;
|
||||
|
||||
return (
|
||||
<Image
|
||||
style={{ height: props.height, width: props.width }}
|
||||
source={props.focused ? props.focusedSource : props.source}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default FocusableIcon;
|
||||
48
src/components/Library.tsx
Normal file
48
src/components/Library.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import { Text, View, Image } from 'react-native';
|
||||
|
||||
const SectionHeader: React.FC<{ title: string }> = ({ title }) => {
|
||||
return (
|
||||
<View style={{
|
||||
height: 60,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
// backgroundColor: 'green',
|
||||
alignItems: 'center',
|
||||
paddingLeft: 15,
|
||||
paddingRight: 15,
|
||||
}}>
|
||||
<Text style={{
|
||||
color: 'white',
|
||||
fontSize: 34,
|
||||
fontWeight: 'normal',
|
||||
fontFamily: 'Rubik-VariableFont_wght',
|
||||
}}>{title}</Text>
|
||||
<Image
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
tintColor: 'white',
|
||||
}}
|
||||
source={require('../../res/chevron_right.png')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const AlbumCoverList = () => {
|
||||
|
||||
}
|
||||
|
||||
const Library = () => (
|
||||
<View style={{
|
||||
flex: 1,
|
||||
backgroundColor: '#3b3b3b',
|
||||
}}>
|
||||
<SectionHeader title='Albums' />
|
||||
<SectionHeader title='Artists' />
|
||||
<SectionHeader title='Playlists' />
|
||||
</View>
|
||||
);
|
||||
|
||||
export default Library;
|
||||
23
src/components/RootNavigator.tsx
Normal file
23
src/components/RootNavigator.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
import TabNavigator from './TabNavigator';
|
||||
import NowPlayingLayout from './NowPlayingLayout';
|
||||
|
||||
const RootStack = createStackNavigator();
|
||||
|
||||
const RootNavigator = () => (
|
||||
<RootStack.Navigator>
|
||||
<RootStack.Screen
|
||||
name='Main'
|
||||
component={TabNavigator}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
<RootStack.Screen
|
||||
name='Now Playing'
|
||||
component={NowPlayingLayout}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
</RootStack.Navigator>
|
||||
);
|
||||
|
||||
export default RootNavigator;
|
||||
@@ -7,6 +7,7 @@ import { musicDb, settingsDb } from '../clients';
|
||||
import { appSettingsState, serversState } from '../state/settings';
|
||||
import { DbStorage } from '../storage/db';
|
||||
import { StackScreenProps } from '@react-navigation/stack';
|
||||
import { useNavigation } from '@react-navigation/core';
|
||||
|
||||
const RecreateDbButton: React.FC<{ db: DbStorage, title: string }> = ({ db, title }) => {
|
||||
const [inProgress, setInProgress] = useState(false);
|
||||
@@ -31,10 +32,15 @@ const RecreateDbButton: React.FC<{ db: DbStorage, title: string }> = ({ db, titl
|
||||
}
|
||||
|
||||
const DbControls = () => {
|
||||
const navigation = useNavigation();
|
||||
return (
|
||||
<View>
|
||||
<RecreateDbButton db={musicDb} title='Music' />
|
||||
<RecreateDbButton db={settingsDb} title='Settings' />
|
||||
<Button
|
||||
title='Now Playing'
|
||||
onPress={() => navigation.navigate('Now Playing')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
58
src/components/TabNavigator.tsx
Normal file
58
src/components/TabNavigator.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import SettingsView from './Settings';
|
||||
import NowPlayingLayout from './NowPlayingLayout';
|
||||
import ArtistsList from './ArtistsList';
|
||||
import FocusableIcon from './FocusableIcon';
|
||||
import Library from './Library';
|
||||
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
const TabNavigator = () => {
|
||||
return (
|
||||
<Tab.Navigator>
|
||||
<Tab.Screen
|
||||
name='Home'
|
||||
component={ArtistsList}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => FocusableIcon({ focused,
|
||||
source: require('../../res/home.png'),
|
||||
focusedSource: require('../../res/home-fill.png'),
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name='Library'
|
||||
component={Library}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => FocusableIcon({ focused,
|
||||
source: require('../../res/library.png'),
|
||||
focusedSource: require('../../res/library-fill.png'),
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name='Search'
|
||||
component={NowPlayingLayout}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => FocusableIcon({ focused,
|
||||
source: require('../../res/search.png'),
|
||||
focusedSource: require('../../res/search-fill.png'),
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name='Settings'
|
||||
component={SettingsView}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => FocusableIcon({ focused,
|
||||
source: require('../../res/settings.png'),
|
||||
focusedSource: require('../../res/settings-fill.png'),
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
export default TabNavigator;
|
||||
Reference in New Issue
Block a user