mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-29 09:29:29 +01:00
basic progress bar
This commit is contained in:
parent
24b443fd70
commit
acc7759495
@ -2,9 +2,11 @@ import { useAtomValue } from 'jotai/utils'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Pressable, StatusBar, StyleSheet, Text, useWindowDimensions, View } from 'react-native'
|
import { Pressable, StatusBar, StyleSheet, Text, useWindowDimensions, View } from 'react-native'
|
||||||
import FastImage from 'react-native-fast-image'
|
import FastImage from 'react-native-fast-image'
|
||||||
import TrackPlayer, { State } from 'react-native-track-player'
|
import TrackPlayer, { State, useProgress } from 'react-native-track-player'
|
||||||
import { currentQueueNameAtom, currentTrackAtom, playerStateAtom } from '../state/trackplayer'
|
import { currentQueueNameAtom, currentTrackAtom, playerStateAtom } from '../state/trackplayer'
|
||||||
import text from '../styles/text'
|
import colors from '../styles/colors'
|
||||||
|
import text, { Font } from '../styles/text'
|
||||||
|
import { formatDuration } from '../util'
|
||||||
import CoverArt from './common/CoverArt'
|
import CoverArt from './common/CoverArt'
|
||||||
import ImageGradientBackground from './common/ImageGradientBackground'
|
import ImageGradientBackground from './common/ImageGradientBackground'
|
||||||
|
|
||||||
@ -96,6 +98,69 @@ const infoStyles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const SeekBar = () => {
|
||||||
|
const { position, duration } = useProgress(250)
|
||||||
|
|
||||||
|
let progress = 0
|
||||||
|
if (duration > 0) {
|
||||||
|
progress = position / duration
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={seekStyles.container}>
|
||||||
|
<View style={seekStyles.barContainer}>
|
||||||
|
<View style={{ ...seekStyles.bars, ...seekStyles.barLeft, flex: progress }} />
|
||||||
|
<View style={{ ...seekStyles.indicator, opacity: progress ? 1 : 0 }} />
|
||||||
|
<View style={{ ...seekStyles.bars, ...seekStyles.barRight, flex: 1 - progress }} />
|
||||||
|
</View>
|
||||||
|
<View style={seekStyles.textContainer}>
|
||||||
|
<Text style={seekStyles.text}>{formatDuration(position)}</Text>
|
||||||
|
<Text style={seekStyles.text}>{formatDuration(duration)}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const seekStyles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
width: '100%',
|
||||||
|
marginTop: 40,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
},
|
||||||
|
barContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 6,
|
||||||
|
},
|
||||||
|
bars: {
|
||||||
|
backgroundColor: colors.text.primary,
|
||||||
|
height: 4,
|
||||||
|
},
|
||||||
|
barLeft: {
|
||||||
|
marginRight: -6,
|
||||||
|
},
|
||||||
|
barRight: {
|
||||||
|
opacity: 0.3,
|
||||||
|
marginLeft: -6,
|
||||||
|
},
|
||||||
|
indicator: {
|
||||||
|
height: 12,
|
||||||
|
width: 12,
|
||||||
|
borderRadius: 6,
|
||||||
|
backgroundColor: colors.text.primary,
|
||||||
|
elevation: 1,
|
||||||
|
},
|
||||||
|
textContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontFamily: Font.regular,
|
||||||
|
fontSize: 15,
|
||||||
|
color: colors.text.primary,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const PlayerControls = () => {
|
const PlayerControls = () => {
|
||||||
const state = useAtomValue(playerStateAtom)
|
const state = useAtomValue(playerStateAtom)
|
||||||
|
|
||||||
@ -148,7 +213,7 @@ const controlsStyles = StyleSheet.create({
|
|||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
marginTop: 40,
|
marginTop: 10,
|
||||||
},
|
},
|
||||||
skip: {
|
skip: {
|
||||||
height: 40,
|
height: 40,
|
||||||
@ -180,6 +245,7 @@ const NowPlayingLayout = () => {
|
|||||||
<NowPlayingHeader />
|
<NowPlayingHeader />
|
||||||
<SongCoverArt />
|
<SongCoverArt />
|
||||||
<SongInfo />
|
<SongInfo />
|
||||||
|
<SeekBar />
|
||||||
<PlayerControls />
|
<PlayerControls />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import { TextStyle } from 'react-native'
|
import { TextStyle } from 'react-native'
|
||||||
import colors from './colors'
|
import colors from './colors'
|
||||||
|
|
||||||
const fontRegular = 'Metropolis-Regular'
|
export enum Font {
|
||||||
const fontSemiBold = 'Metropolis-SemiBold'
|
regular = 'Metropolis-Regular',
|
||||||
const fontBold = 'Metropolis-Bold'
|
semiBold = 'Metropolis-SemiBold',
|
||||||
|
bold = 'Metropolis-Bold',
|
||||||
|
}
|
||||||
|
|
||||||
const paragraph: TextStyle = {
|
const paragraph: TextStyle = {
|
||||||
fontFamily: fontRegular,
|
fontFamily: Font.regular,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: colors.text.primary,
|
color: colors.text.primary,
|
||||||
}
|
}
|
||||||
@ -14,19 +16,19 @@ const paragraph: TextStyle = {
|
|||||||
const header: TextStyle = {
|
const header: TextStyle = {
|
||||||
...paragraph,
|
...paragraph,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontFamily: fontSemiBold,
|
fontFamily: Font.semiBold,
|
||||||
}
|
}
|
||||||
|
|
||||||
const title: TextStyle = {
|
const title: TextStyle = {
|
||||||
...paragraph,
|
...paragraph,
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontFamily: fontBold,
|
fontFamily: Font.bold,
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemTitle: TextStyle = {
|
const itemTitle: TextStyle = {
|
||||||
...paragraph,
|
...paragraph,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: fontSemiBold,
|
fontFamily: Font.semiBold,
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemSubtitle: TextStyle = {
|
const itemSubtitle: TextStyle = {
|
||||||
@ -38,7 +40,7 @@ const itemSubtitle: TextStyle = {
|
|||||||
const songListTitle: TextStyle = {
|
const songListTitle: TextStyle = {
|
||||||
...paragraph,
|
...paragraph,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontFamily: fontSemiBold,
|
fontFamily: Font.semiBold,
|
||||||
}
|
}
|
||||||
|
|
||||||
const songListSubtitle: TextStyle = {
|
const songListSubtitle: TextStyle = {
|
||||||
@ -55,7 +57,7 @@ const xsmall: TextStyle = {
|
|||||||
const button: TextStyle = {
|
const button: TextStyle = {
|
||||||
...paragraph,
|
...paragraph,
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontFamily: fontBold,
|
fontFamily: Font.bold,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
export function formatDuration(seconds: number): string {
|
export function formatDuration(seconds: number): string {
|
||||||
const s = seconds % 60
|
const s = Math.floor(seconds) % 60
|
||||||
const m = Math.floor(seconds / 60) % 60
|
const m = Math.floor(seconds / 60) % 60
|
||||||
const h = Math.floor(seconds / 60 / 60)
|
const h = Math.floor(seconds / 60 / 60)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user