Add repeat mode

This commit is contained in:
Lei Nelissen
2020-08-28 14:17:54 +02:00
parent 12b53eca4a
commit 3026fdf4da
4 changed files with 81 additions and 1 deletions

1
src/assets/repeat.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 106.69 89.45"><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="Regular-M"><path d="M0,41.16a5.37,5.37,0,0,0,10.74,0V37.94c0-7.76,5.37-12.89,13.38-12.89H60.94v10.2a4.05,4.05,0,0,0,4.39,4.3,5.27,5.27,0,0,0,3.32-1.22L87.11,23.1a4.1,4.1,0,0,0,0-6.55L68.65,1.22A5.57,5.57,0,0,0,65.33,0a4.09,4.09,0,0,0-4.39,4.35v10.1H25.15C9.77,14.45,0,23.29,0,37.16ZM45.75,54.25A4,4,0,0,0,41.36,50a5.25,5.25,0,0,0-3.27,1.17L19.63,66.36a4,4,0,0,0,0,6.54L38.09,88.23a5,5,0,0,0,3.27,1.22,4,4,0,0,0,4.39-4.29V75H81.54c15.38,0,25.15-8.89,25.15-22.7v-4a5.37,5.37,0,1,0-10.74,0v3.22c0,7.72-5.37,12.9-13.38,12.9H45.75Z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 695 B

1
src/assets/shuffle.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 114.69 90.97"><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="Symbols"><g id="Regular-M"><path d="M0,70.51c0,3.12,2.29,5.27,5.76,5.27H16.85c8.44,0,13.47-2.44,19.58-9.52L47.36,53.47l11,12.79c6,7.08,11.08,9.57,19.58,9.57h9V86.67A4,4,0,0,0,91.26,91a5.27,5.27,0,0,0,3.32-1.22L113,74.51A4.08,4.08,0,0,0,113,68L94.58,52.64a5.27,5.27,0,0,0-3.32-1.22,4,4,0,0,0-4.35,4.29v9.48H78.22c-5.08,0-8.2-1.62-12.16-6.25L54.39,45.31,66.06,31.74c4-4.69,7.08-6.3,12.16-6.3h8.69v9.81a4,4,0,0,0,4.35,4.3,5.27,5.27,0,0,0,3.32-1.22L113,23.1a4.09,4.09,0,0,0,0-6.55L94.58,1.22A5.27,5.27,0,0,0,91.26,0a4,4,0,0,0-4.35,4.3V14.84h-9c-8.5,0-13.57,2.49-19.58,9.57l-11,12.8L36.43,24.41c-6.11-7.08-11.14-9.57-19.58-9.57H5.76C2.29,14.84,0,17,0,20.17s2.34,5.32,5.76,5.32H17.09c4.69,0,7.67,1.61,11.67,6.25L40.43,45.31,28.76,58.94c-4.05,4.63-7,6.25-11.67,6.25H5.76C2.34,65.19,0,67.38,0,70.51Z"/></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 964 B

View File

@@ -4,4 +4,9 @@ export const Header = styled.Text`
margin: 24px 0 12px 0;
font-size: 36px;
font-weight: bold;
`;
export const SubHeader = styled.Text`
font-size: 24px;
margin: 12px 0;
`;

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState, useCallback, useEffect, useRef } from 'react';
import TrackPlayer, { usePlaybackState, STATE_PLAYING, STATE_PAUSED } from 'react-native-track-player';
import { TouchableOpacity } from 'react-native';
import styled from 'styled-components/native';
@@ -7,9 +7,13 @@ import ForwardIcon from 'assets/forwards.svg';
import BackwardIcon from 'assets/backwards.svg';
import PlayIcon from 'assets/play.svg';
import PauseIcon from 'assets/pause.svg';
import RepeatIcon from 'assets/repeat.svg';
// import ShuffleIcon from 'assets/shuffle.svg';
import { useColorScheme } from 'react-native-appearance';
import { THEME_COLOR } from 'CONSTANTS';
const BUTTON_SIZE = 40;
const BUTTON_SIZE_SMALL = 25;
const pause = () => TrackPlayer.pause();
const play = () => TrackPlayer.play();
@@ -47,6 +51,14 @@ export default function MediaControls() {
<NextButton fill={fill} />
</Button>
</Buttons>
<Buttons>
<Button>
<RepeatButton fill={fill} />
</Button>
<Button>
{/* <ShuffleButton fill={fill} /> */}
</Button>
</Buttons>
</Container>
);
}
@@ -71,6 +83,67 @@ export function NextButton({ fill }: { fill: string }) {
);
}
export function RepeatButton({ fill }: { fill: string}) {
const [isRepeating, setRepeating] = useState(false);
const handlePress = useCallback(() => setRepeating(!isRepeating), [isRepeating, setRepeating]);
const listener = useRef<TrackPlayer.EmitterSubscription | null>(null);
// The callback that should determine whether we need to repeeat or not
const handleEndEvent = useCallback(async () => {
if (isRepeating) {
// Retrieve all current tracks
const tracks = await TrackPlayer.getQueue();
// Then skip to the first track
await TrackPlayer.skip(tracks[0].id);
// Cautiously reset the seek time, as there might only be a single
// item in queue.
await TrackPlayer.seekTo(0);
// Then play the item
await TrackPlayer.play();
}
}, [isRepeating]);
// Subscribe to ended event handler so that we can restart the queue from
// the start if looping is enabled
useEffect(() => {
// Set the event listener
listener.current = TrackPlayer.addEventListener('playback-queue-ended', handleEndEvent);
// Then clean up after
return function cleanup() {
listener?.current?.remove();
};
}, [handleEndEvent]);
return (
<TouchableOpacity onPress={handlePress} style={{ opacity: isRepeating ? 1 : 0.5 }}>
<RepeatIcon
width={BUTTON_SIZE_SMALL}
height={BUTTON_SIZE_SMALL}
fill={isRepeating ? THEME_COLOR : fill}
/>
</TouchableOpacity>
);
}
// export function ShuffleButton({ fill }: { fill: string}) {
// const [isShuffling, setShuffling] = useState(false);
// const handlePress = useCallback(() => setShuffling(!isShuffling), [isShuffling, setShuffling]);
// return (
// <TouchableOpacity onPress={handlePress} style={{ opacity: isShuffling ? 1 : 0.5 }}>
// <ShuffleIcon
// width={BUTTON_SIZE_SMALL}
// height={BUTTON_SIZE_SMALL}
// fill={isShuffling ? THEME_COLOR : fill}
// />
// </TouchableOpacity>
// );
// }
export function MainButton({ fill }: { fill: string }) {
const state = usePlaybackState();