Moved control bar into it's own component and fixed itslayout on mobile
This commit is contained in:
183
front/components/Play/PlayViewControlBar.tsx
Normal file
183
front/components/Play/PlayViewControlBar.tsx
Normal file
@@ -0,0 +1,183 @@
|
||||
import { View } from 'react-native';
|
||||
import * as React from 'react';
|
||||
import { Row, Image, Text, Icon, useBreakpointValue } from 'native-base';
|
||||
import IconButton from '../IconButton';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { MetronomeControls } from '../Metronome';
|
||||
import StarProgress from '../StarProgress';
|
||||
import Song from '../../models/Song';
|
||||
import useColorScheme from '../../hooks/colorScheme';
|
||||
import { useTheme } from 'native-base';
|
||||
|
||||
type PlayViewControlBarProps = {
|
||||
song: Song;
|
||||
time: number;
|
||||
paused: boolean;
|
||||
score: number;
|
||||
onResume: () => void;
|
||||
onPause: () => void;
|
||||
onEnd: () => void;
|
||||
};
|
||||
|
||||
const PlayViewControlBar = ({
|
||||
song,
|
||||
time,
|
||||
paused,
|
||||
score,
|
||||
onResume,
|
||||
onPause,
|
||||
onEnd,
|
||||
}: PlayViewControlBarProps) => {
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
|
||||
const isPhone = screenSize === 'small';
|
||||
const bpm = React.useRef<number>(60);
|
||||
const colorScheme = useColorScheme();
|
||||
const { colors } = useTheme();
|
||||
const textColor = colors.text;
|
||||
const statColor = colors.lightText;
|
||||
return (
|
||||
<Row
|
||||
style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
gap: 5,
|
||||
borderRadius: 12,
|
||||
backgroundColor: 'rgba(16, 16, 20, 0.5)',
|
||||
//@ts-expect-error backdropFilter is not in the types
|
||||
backdropFilter: 'blur(2px)',
|
||||
padding: isPhone ? 5 : 10,
|
||||
marginTop: 20,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexGrow: 0,
|
||||
flexShrink: 3,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: isPhone ? undefined : 40,
|
||||
minWidth: 160,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: isPhone ? 5 : 20,
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={song.cover}
|
||||
alt="cover"
|
||||
size={isPhone ? '2sm' : 'sm'}
|
||||
borderRadius={8}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
aspectRatio: 1,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
gap: 8,
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
}}
|
||||
>
|
||||
<Text color={textColor[800]} fontSize={14} maxW={'100%'} isTruncated>
|
||||
{song.name}
|
||||
</Text>
|
||||
<Text color={textColor[900]} fontSize={12} maxW={'100%'} isTruncated>
|
||||
{song.artistId}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: isPhone ? 10 : 25,
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="solid"
|
||||
icon={
|
||||
<Icon
|
||||
as={Ionicons}
|
||||
color={colors.coolGray[900]}
|
||||
name={paused ? 'play' : 'pause'}
|
||||
/>
|
||||
}
|
||||
onPress={() => {
|
||||
if (paused) {
|
||||
onResume();
|
||||
} else {
|
||||
onPause();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{true && (
|
||||
<>
|
||||
<IconButton
|
||||
size="sm"
|
||||
colorScheme="coolGray"
|
||||
variant="solid"
|
||||
icon={<Icon as={Ionicons} name="stop" />}
|
||||
onPress={() => {
|
||||
onEnd();
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Text color={textColor[900]}>
|
||||
{time < 0
|
||||
? paused
|
||||
? '0:00'
|
||||
: Math.floor((time % 60000) / 1000)
|
||||
.toFixed(0)
|
||||
.toString()
|
||||
: `${Math.floor(time / 60000)}:${Math.floor((time % 60000) / 1000)
|
||||
.toFixed(0)
|
||||
.toString()
|
||||
.padStart(2, '0')}`}
|
||||
</Text>
|
||||
<StarProgress
|
||||
value={score}
|
||||
max={100}
|
||||
starSteps={[50, 75, 90]}
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
minWidth: isPhone ? 50 : 200,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: 'space-evenly',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
marginLeft: isPhone ? undefined : 40,
|
||||
maxWidth: 250,
|
||||
minWidth: 120,
|
||||
}}
|
||||
>
|
||||
<MetronomeControls paused={paused} bpm={bpm.current} />
|
||||
</View>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayViewControlBar;
|
||||
@@ -14,20 +14,20 @@ const StarProgress = (props: StarProgressProps) => {
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
props.style,
|
||||
{
|
||||
position: 'relative',
|
||||
flex: 1,
|
||||
maxWidth: 600,
|
||||
justifyContent: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
props.style,
|
||||
]}
|
||||
>
|
||||
<Progress
|
||||
color={'#6075F9'}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
flex: 1,
|
||||
}}
|
||||
value={props.value}
|
||||
max={props.max}
|
||||
@@ -42,8 +42,8 @@ const StarProgress = (props: StarProgressProps) => {
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: `${(step / props.max) * 100}%`,
|
||||
top: '45%',
|
||||
transform: 'translate(-50%, -55%)',
|
||||
// top: '50%',
|
||||
// transform: 'translate(-50%, -55%)',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -36,6 +36,8 @@ import { useTheme } from 'native-base';
|
||||
import PopupCC from '../components/UI/PopupCC';
|
||||
import ButtonBase from '../components/UI/ButtonBase';
|
||||
import { Clock, Cup } from 'iconsax-react-native';
|
||||
import PlayViewControlBar from '../components/Play/PlayViewControlBar';
|
||||
import { PlageHandler } from '../models/Plage';
|
||||
|
||||
type PlayViewProps = {
|
||||
songId: number;
|
||||
@@ -79,6 +81,7 @@ export const PianoCC = createContext<PianoCanvasContext>({
|
||||
});
|
||||
|
||||
const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
|
||||
songId = 1;
|
||||
const [type, setType] = useState<'practice' | 'normal'>();
|
||||
const accessToken = useSelector((state: RootState) => state.user.accessToken);
|
||||
const navigation = useNavigation();
|
||||
@@ -332,7 +335,7 @@ const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
|
||||
zIndex: 100,
|
||||
}}
|
||||
>
|
||||
<PopupCC
|
||||
{/* <PopupCC
|
||||
title={translate('selectPlayMode')}
|
||||
description={translate('selectPlayModeExplaination')}
|
||||
isVisible={type === undefined}
|
||||
@@ -361,7 +364,7 @@ const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
|
||||
onPress={async () => setType('normal')}
|
||||
/>
|
||||
</Row>
|
||||
</PopupCC>
|
||||
</PopupCC> */}
|
||||
{(
|
||||
[
|
||||
[
|
||||
@@ -479,10 +482,21 @@ const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
|
||||
</PianoCC.Provider>
|
||||
{!partitionRendered && <LoadingComponent />}
|
||||
</View>
|
||||
<PlayViewControlBar
|
||||
score={score}
|
||||
time={time}
|
||||
paused={paused}
|
||||
song={song.data}
|
||||
onEnd={() => {}}
|
||||
onPause={() => {}}
|
||||
onResume={() => {}}
|
||||
/>
|
||||
|
||||
<Row
|
||||
{/* <Row
|
||||
justifyContent="space-between"
|
||||
style={{
|
||||
maxHeight: 100,
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
@@ -614,7 +628,7 @@ const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
|
||||
marginBottom: 10,
|
||||
minWidth: 200,
|
||||
}}
|
||||
/>
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
@@ -629,7 +643,7 @@ const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
|
||||
>
|
||||
<MetronomeControls paused={paused} bpm={bpm.current} />
|
||||
</View>
|
||||
</Row>
|
||||
</Row> */}
|
||||
</SafeAreaView>
|
||||
{colorScheme === 'dark' && (
|
||||
<LinearGradient
|
||||
|
||||
Reference in New Issue
Block a user