Transform Queue component into FlatList
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import useQueue from 'utility/useQueue';
|
import useQueue from 'utility/useQueue';
|
||||||
import { View, StyleSheet } from 'react-native';
|
import { View, StyleSheet, ListRenderItemInfo } from 'react-native';
|
||||||
import styled, { css } from 'styled-components/native';
|
import styled, { css } from 'styled-components/native';
|
||||||
import useCurrentTrack from 'utility/useCurrentTrack';
|
import useCurrentTrack from 'utility/useCurrentTrack';
|
||||||
import TouchableHandler from 'components/TouchableHandler';
|
import TouchableHandler from 'components/TouchableHandler';
|
||||||
import TrackPlayer, { RepeatMode } from 'react-native-track-player';
|
import TrackPlayer, { RepeatMode, Track } from 'react-native-track-player';
|
||||||
import { t } from '@localisation';
|
import { t } from '@localisation';
|
||||||
import useDefaultStyles from 'components/Colors';
|
import useDefaultStyles from 'components/Colors';
|
||||||
import { Text } from 'components/Typography';
|
import { Text } from 'components/Typography';
|
||||||
@@ -17,15 +17,16 @@ import ticksToDuration from 'utility/ticksToDuration';
|
|||||||
|
|
||||||
const ICON_SIZE = 16;
|
const ICON_SIZE = 16;
|
||||||
|
|
||||||
const Container = styled.View`
|
const Container = styled.FlatList<Track>`
|
||||||
margin-top: 56px;
|
padding: 40px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Header = styled.View`
|
const Header = styled.View`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
padding-top: 52px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const IconButton = styled.TouchableOpacity`
|
const IconButton = styled.TouchableOpacity`
|
||||||
@@ -56,7 +57,8 @@ const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean, isDar
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const ClearQueue = styled.View`
|
const ClearQueue = styled.View`
|
||||||
margin: 20px 0;
|
padding: 20px 0;
|
||||||
|
padding-bottom: 80px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
@@ -65,7 +67,11 @@ const styles = StyleSheet.create({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function Queue() {
|
interface Props {
|
||||||
|
header?: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Queue({ header }: Props) {
|
||||||
const defaultStyles = useDefaultStyles();
|
const defaultStyles = useDefaultStyles();
|
||||||
const queue = useQueue();
|
const queue = useQueue();
|
||||||
const [isRepeating, setIsRepeating] = useState(false);
|
const [isRepeating, setIsRepeating] = useState(false);
|
||||||
@@ -96,41 +102,47 @@ export default function Queue() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container
|
||||||
<Header>
|
data={queue}
|
||||||
<Text>{t('queue')}</Text>
|
ListHeaderComponent={
|
||||||
<Divider style={{ marginHorizontal: 18 }} />
|
<>
|
||||||
<IconButton
|
{header}
|
||||||
style={isRepeating ? defaultStyles.activeBackground : undefined}
|
<Header>
|
||||||
onPress={toggleLoop}
|
<Text>{t('queue')}</Text>
|
||||||
>
|
<Divider style={{ marginHorizontal: 18 }} />
|
||||||
<RepeatIcon
|
<IconButton
|
||||||
fill={isRepeating ? THEME_COLOR : defaultStyles.textHalfOpacity.color}
|
style={isRepeating ? defaultStyles.activeBackground : undefined}
|
||||||
width={ICON_SIZE}
|
onPress={toggleLoop}
|
||||||
height={ICON_SIZE}
|
>
|
||||||
/>
|
<RepeatIcon
|
||||||
</IconButton>
|
fill={isRepeating ? THEME_COLOR : defaultStyles.textHalfOpacity.color}
|
||||||
</Header>
|
width={ICON_SIZE}
|
||||||
{queue.map((track, i) => (
|
height={ICON_SIZE}
|
||||||
<TouchableHandler id={i} onPress={playTrack} key={i}>
|
/>
|
||||||
|
</IconButton>
|
||||||
|
</Header>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
renderItem={({ item: track, index}: ListRenderItemInfo<Track>) => (
|
||||||
|
<TouchableHandler id={index} onPress={playTrack} key={index}>
|
||||||
<QueueItem
|
<QueueItem
|
||||||
active={currentIndex === i}
|
active={currentIndex === index}
|
||||||
key={i}
|
key={index}
|
||||||
alreadyPlayed={currentIndex ? i < currentIndex : false}
|
alreadyPlayed={currentIndex ? index < currentIndex : false}
|
||||||
style={[
|
style={[
|
||||||
defaultStyles.border,
|
defaultStyles.border,
|
||||||
currentIndex === i ? defaultStyles.activeBackground : {},
|
currentIndex === index ? defaultStyles.activeBackground : {},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<View style={{ flex: 1, marginRight: 16 }}>
|
<View style={{ flex: 1, marginRight: 16 }}>
|
||||||
<Text
|
<Text
|
||||||
style={[currentIndex === i ? { color: THEME_COLOR, fontWeight: '500' } : styles.trackTitle, { marginBottom: 2 }]}
|
style={[currentIndex === index ? { color: THEME_COLOR, fontWeight: '500' } : styles.trackTitle, { marginBottom: 2 }]}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
>
|
>
|
||||||
{track.title}
|
{track.title}
|
||||||
</Text>
|
</Text>
|
||||||
<TextHalfOpacity
|
<TextHalfOpacity
|
||||||
style={currentIndex === i ? { color: THEME_COLOR, fontWeight: '400' } : undefined}
|
style={currentIndex === index ? { color: THEME_COLOR, fontWeight: '400' } : undefined}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
>
|
>
|
||||||
{track.artist}{track.album && ' — ' + track.album}
|
{track.artist}{track.album && ' — ' + track.album}
|
||||||
@@ -138,20 +150,23 @@ export default function Queue() {
|
|||||||
</View>
|
</View>
|
||||||
<View style={{ marginLeft: 'auto', marginRight: 8 }}>
|
<View style={{ marginLeft: 'auto', marginRight: 8 }}>
|
||||||
<TextHalfOpacity
|
<TextHalfOpacity
|
||||||
style={currentIndex === i ? { color: THEME_COLOR, fontWeight: '400' } : undefined}
|
style={currentIndex === index ? { color: THEME_COLOR, fontWeight: '400' } : undefined}
|
||||||
>
|
>
|
||||||
{ticksToDuration(track.duration || 0)}
|
{ticksToDuration(track.duration || 0)}
|
||||||
</TextHalfOpacity>
|
</TextHalfOpacity>
|
||||||
</View>
|
</View>
|
||||||
<View>
|
<View>
|
||||||
<DownloadIcon trackId={track.backendId} fill={currentIndex === i ? THEME_COLOR + '80' : undefined} />
|
<DownloadIcon trackId={track.backendId} fill={currentIndex === index ? THEME_COLOR + '80' : undefined} />
|
||||||
</View>
|
</View>
|
||||||
</QueueItem>
|
</QueueItem>
|
||||||
</TouchableHandler>
|
</TouchableHandler>
|
||||||
))}
|
|
||||||
<ClearQueue>
|
)}
|
||||||
<Button title={t('clear-queue')} onPress={clearQueue} />
|
ListFooterComponent={(
|
||||||
</ClearQueue>
|
<ClearQueue>
|
||||||
</Container>
|
<Button title={t('clear-queue')} onPress={clearQueue} />
|
||||||
|
</ClearQueue>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,34 +1,24 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
import MediaControls from './components/MediaControls';
|
import MediaControls from './components/MediaControls';
|
||||||
import ProgressBar from './components/ProgressBar';
|
import ProgressBar from './components/ProgressBar';
|
||||||
import NowPlaying from './components/NowPlaying';
|
import NowPlaying from './components/NowPlaying';
|
||||||
import Queue from './components/Queue';
|
import Queue from './components/Queue';
|
||||||
import useDefaultStyles from 'components/Colors';
|
|
||||||
import ConnectionNotice from './components/ConnectionNotice';
|
import ConnectionNotice from './components/ConnectionNotice';
|
||||||
import { ScrollView } from 'react-native-gesture-handler';
|
|
||||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||||
import StreamStatus from './components/StreamStatus';
|
import StreamStatus from './components/StreamStatus';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
export default function Player() {
|
||||||
inner: {
|
|
||||||
padding: 40,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function Player() {
|
|
||||||
const defaultStyles = useDefaultStyles();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GestureHandlerRootView style={{ flex: 1 }}>
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||||
<ScrollView contentContainerStyle={styles.inner} style={defaultStyles.view}>
|
<Queue header={(
|
||||||
<NowPlaying />
|
<>
|
||||||
<ConnectionNotice />
|
<NowPlaying />
|
||||||
<StreamStatus />
|
<ConnectionNotice />
|
||||||
<ProgressBar />
|
<StreamStatus />
|
||||||
<MediaControls />
|
<ProgressBar />
|
||||||
<Queue />
|
<MediaControls />
|
||||||
</ScrollView>
|
</>
|
||||||
|
)} />
|
||||||
</GestureHandlerRootView>
|
</GestureHandlerRootView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user