First overhaul of search screen
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useRef, ReactText } from 'react';
|
||||
import { useGetImage } from 'utility/JellyfinApi';
|
||||
import { MusicNavigationProp } from '../types';
|
||||
import { Text, SafeAreaView, SectionList, View } from 'react-native';
|
||||
import { SafeAreaView, SectionList, View } from 'react-native';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { differenceInDays } from 'date-fns';
|
||||
@@ -9,13 +9,16 @@ import { useTypedSelector } from 'store';
|
||||
import { fetchAllAlbums } from 'store/music/actions';
|
||||
import { ALBUM_CACHE_AMOUNT_OF_DAYS } from 'CONSTANTS';
|
||||
import TouchableHandler from 'components/TouchableHandler';
|
||||
import AlbumImage, { AlbumItem } from './components/AlbumImage';
|
||||
import AlbumImage, { AlbumHeight, AlbumItem } from './components/AlbumImage';
|
||||
import { selectAlbumsByAlphabet, SectionedId } from 'store/music/selectors';
|
||||
import AlphabetScroller from 'components/AlphabetScroller';
|
||||
import { EntityId } from '@reduxjs/toolkit';
|
||||
import styled from 'styled-components/native';
|
||||
import useDefaultStyles from 'components/Colors';
|
||||
import useDefaultStyles, { ColoredBlurView } from 'components/Colors';
|
||||
import { Album } from 'store/music/types';
|
||||
import { Text } from 'components/Typography';
|
||||
|
||||
const HeadingHeight = 50;
|
||||
|
||||
interface VirtualizedItemInfo {
|
||||
section: SectionedId,
|
||||
@@ -40,25 +43,25 @@ function generateSection({ section }: { section: SectionedId }) {
|
||||
}
|
||||
|
||||
const SectionContainer = styled.View`
|
||||
border-bottom-width: 1px;
|
||||
height: 50px;
|
||||
height: ${HeadingHeight}px;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
padding: 0 24px;
|
||||
`;
|
||||
|
||||
const SectionText = styled.Text`
|
||||
const SectionText = styled(Text)`
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
font-weight: 400;
|
||||
`;
|
||||
|
||||
const SectionHeading = React.memo(function SectionHeading(props: { label: string }) {
|
||||
const defaultStyles = useDefaultStyles();
|
||||
const { label } = props;
|
||||
|
||||
return (
|
||||
<SectionContainer style={defaultStyles.sectionHeading}>
|
||||
<SectionText style={defaultStyles.text}>{label}</SectionText>
|
||||
</SectionContainer>
|
||||
<ColoredBlurView>
|
||||
<SectionContainer>
|
||||
<SectionText>{label}</SectionText>
|
||||
</SectionContainer>
|
||||
</ColoredBlurView>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -118,21 +121,20 @@ const Albums: React.FC = () => {
|
||||
|
||||
// We can then determine the "length" (=height) of this item. Header items
|
||||
// end up with an itemIndex of -1, thus are easy to identify.
|
||||
const length = header ? 50 : (itemIndex % 2 === 0 ? 220 : 0);
|
||||
const length = header ? 50 : (itemIndex % 2 === 0 ? AlbumHeight : 0);
|
||||
|
||||
// We'll also need to account for any unevenly-ended lists up until the
|
||||
// current item.
|
||||
const previousRows = data?.filter((row, i) => i < sectionIndex)
|
||||
.reduce((sum, row) => sum + Math.ceil(row.data.length / 2), 0) || 0;
|
||||
|
||||
|
||||
// We must also calcuate the offset, total distance from the top of the
|
||||
// screen. First off, we'll account for each sectionIndex that is shown up
|
||||
// until now. This only includes the heading for the current section if the
|
||||
// item is not the section header
|
||||
const headingOffset = 50 * (header ? sectionIndex : sectionIndex + 1);
|
||||
const headingOffset = HeadingHeight * (header ? sectionIndex : sectionIndex + 1);
|
||||
const currentRows = itemIndex > 1 ? Math.ceil((itemIndex + 1) / 2) : 0;
|
||||
const itemOffset = 220 * (previousRows + currentRows);
|
||||
const itemOffset = AlbumHeight * (previousRows + currentRows);
|
||||
const offset = headingOffset + itemOffset;
|
||||
|
||||
return { index, length, offset };
|
||||
@@ -189,7 +191,7 @@ const Albums: React.FC = () => {
|
||||
onRefresh={retrieveData}
|
||||
getItemLayout={getItemLayout}
|
||||
ref={listRef}
|
||||
keyExtractor={(item, index) => `${item}_${index}`}
|
||||
keyExtractor={(item) => item as string}
|
||||
renderSectionHeader={generateSection}
|
||||
renderItem={generateItem}
|
||||
/>
|
||||
|
||||
@@ -15,17 +15,23 @@ import ListButton from 'components/ListButton';
|
||||
import { t } from '@localisation';
|
||||
import useDefaultStyles from 'components/Colors';
|
||||
import { Album } from 'store/music/types';
|
||||
import Divider from 'components/Divider';
|
||||
import styled from 'styled-components/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
columnWrapper: {
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10
|
||||
paddingHorizontal: 16,
|
||||
}
|
||||
});
|
||||
|
||||
const HeaderContainer = styled.View`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const NavigationHeader: React.FC = () => {
|
||||
const navigation = useNavigation<MusicNavigationProp>();
|
||||
const defaultStyles = useDefaultStyles();
|
||||
const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]);
|
||||
const handlePlaylistsClick = useCallback(() => { navigation.navigate('Playlists'); }, [navigation]);
|
||||
|
||||
@@ -34,7 +40,10 @@ const NavigationHeader: React.FC = () => {
|
||||
<ListButton onPress={handleAllAlbumsClick}>{t('all-albums')}</ListButton>
|
||||
<ListButton onPress={handlePlaylistsClick}>{t('playlists')}</ListButton>
|
||||
<ListContainer>
|
||||
<Header style={defaultStyles.text}>{t('recent-albums')}</Header>
|
||||
<HeaderContainer>
|
||||
<Header>{t('recent-albums')}</Header>
|
||||
<Divider style={{ marginLeft: 24 }} />
|
||||
</HeaderContainer>
|
||||
</ListContainer>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -3,17 +3,20 @@ import FastImage from 'react-native-fast-image';
|
||||
import { Dimensions } from 'react-native';
|
||||
|
||||
const Screen = Dimensions.get('screen');
|
||||
export const AlbumWidth = Screen.width / 2 - 24;
|
||||
export const AlbumHeight = AlbumWidth + 40;
|
||||
export const CoverSize = AlbumWidth - 16;
|
||||
|
||||
export const AlbumItem = styled.View`
|
||||
width: ${Screen.width / 2 - 10}px;
|
||||
padding: 10px;
|
||||
height: 220px;
|
||||
width: ${AlbumWidth}px;
|
||||
height: ${AlbumHeight}px;
|
||||
padding: 8px;
|
||||
`;
|
||||
|
||||
const AlbumImage = styled(FastImage)`
|
||||
border-radius: 10px;
|
||||
width: ${Screen.width / 2 - 40}px;
|
||||
height: ${Screen.width / 2 - 40}px;
|
||||
width: ${CoverSize}px;
|
||||
height: ${CoverSize}px;
|
||||
margin-bottom: 5px;
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import styled from 'styled-components/native';
|
||||
|
||||
const ListContainer = styled.View`
|
||||
padding: 10px;
|
||||
padding: 24px;
|
||||
`;
|
||||
|
||||
export default ListContainer;
|
||||
Reference in New Issue
Block a user