move header into its own component

This commit is contained in:
austinried 2021-08-12 13:55:41 +09:00
parent 16b753e2bb
commit 187cce16d9
3 changed files with 109 additions and 115 deletions

View File

@ -0,0 +1,79 @@
import colors from '@app/styles/colors'
import dimensions from '@app/styles/dimensions'
import font from '@app/styles/font'
import { useNavigation } from '@react-navigation/core'
import React, { useCallback } from 'react'
import { View, StatusBar, Text, StyleSheet, ViewStyle } from 'react-native'
import Animated from 'react-native-reanimated'
import PressableOpacity from './PressableOpacity'
import IconMat from 'react-native-vector-icons/MaterialIcons'
import { ReactComponentLike } from 'prop-types'
const HeaderBar = React.memo<{
title?: string
headerStyle?: Animated.AnimatedStyleProp<ViewStyle> | Animated.AnimatedStyleProp<ViewStyle>[]
HeaderCenter?: ReactComponentLike
onMore?: () => void
}>(({ title, headerStyle, HeaderCenter, onMore }) => {
const navigation = useNavigation()
const back = useCallback(() => {
navigation.goBack()
}, [navigation])
const _headerStyle = Array.isArray(headerStyle) ? headerStyle : [headerStyle]
return (
<Animated.View style={[styles.container, ..._headerStyle]}>
<PressableOpacity onPress={back} style={styles.icons} ripple={true}>
<IconMat name="arrow-back" color="white" size={25} />
</PressableOpacity>
<View style={styles.center}>
{HeaderCenter ? (
<HeaderCenter />
) : (
<Text numberOfLines={1} style={styles.title}>
{title}
</Text>
)}
</View>
{onMore ? (
<PressableOpacity style={styles.icons} ripple={true} onPress={onMore}>
<IconMat name="more-vert" color="white" size={25} />
</PressableOpacity>
) : (
<></>
)}
</Animated.View>
)
})
const styles = StyleSheet.create({
container: {
height: dimensions.top(),
paddingTop: StatusBar.currentHeight,
backgroundColor: colors.gradient.high,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
icons: {
height: 42,
width: 42,
marginHorizontal: 8,
},
center: {
flex: 1,
},
title: {
fontFamily: font.semiBold,
fontSize: 18,
color: colors.text.primary,
flex: 1,
textAlignVertical: 'center',
paddingLeft: 14,
},
})
export default HeaderBar

View File

@ -3,8 +3,8 @@ import CoverArt from '@app/components/CoverArt'
import GradientBackground from '@app/components/GradientBackground'
import GradientScrollView from '@app/components/GradientScrollView'
import Header from '@app/components/Header'
import HeaderBar from '@app/components/HeaderBar'
import ListItem from '@app/components/ListItem'
import PressableOpacity from '@app/components/PressableOpacity'
import { useArtistInfo } from '@app/hooks/music'
import { useSetQueue } from '@app/hooks/trackplayer'
import { Album, Song } from '@app/models/music'
@ -13,11 +13,10 @@ import dimensions from '@app/styles/dimensions'
import font from '@app/styles/font'
import { useLayout } from '@react-native-community/hooks'
import { useNavigation } from '@react-navigation/native'
import React, { useCallback } from 'react'
import { ActivityIndicator, StatusBar, StyleSheet, Text, View } from 'react-native'
import React from 'react'
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native'
import FastImage from 'react-native-fast-image'
import Animated, { useAnimatedScrollHandler, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'
import IconMat from 'react-native-vector-icons/MaterialIcons'
import { useAnimatedScrollHandler, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'
const AlbumItem = React.memo<{
album: Album
@ -74,62 +73,6 @@ const ArtistDetailsFallback = React.memo(() => (
</GradientBackground>
))
const NowPlayingHeader = React.memo<{ title: string; animatedOpacity: { opacity: number } }>(
({ title, animatedOpacity }) => {
const navigation = useNavigation()
const back = useCallback(() => {
navigation.goBack()
}, [navigation])
return (
<Animated.View style={[headerStyles.container, animatedOpacity]}>
<PressableOpacity onPress={back} style={headerStyles.icons} ripple={true}>
<IconMat name="arrow-back" color="white" size={25} />
</PressableOpacity>
<View style={headerStyles.center}>
<Text numberOfLines={1} style={headerStyles.queueName}>
{title}
</Text>
</View>
{/* <PressableOpacity style={headerStyles.icons} ripple={true}>
<IconMat name="more-vert" color="white" size={25} />
</PressableOpacity> */}
</Animated.View>
)
},
)
const headerStyles = StyleSheet.create({
container: {
height: dimensions.top(),
paddingTop: StatusBar.currentHeight,
backgroundColor: colors.gradient.high,
width: '100%',
position: 'absolute',
zIndex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
icons: {
height: 42,
width: 42,
marginHorizontal: 8,
},
center: {
flex: 1,
},
queueName: {
fontFamily: font.semiBold,
fontSize: 18,
color: colors.text.primary,
flex: 1,
textAlignVertical: 'center',
paddingLeft: 14,
},
})
const ArtistView = React.memo<{ id: string; title: string }>(({ id, title }) => {
const artist = useArtistInfo(id)
const albumsLayout = useLayout()
@ -160,7 +103,7 @@ const ArtistView = React.memo<{ id: string; title: string }>(({ id, title }) =>
return (
<View style={{ flex: 1 }}>
<NowPlayingHeader title={title} animatedOpacity={animatedOpacity} />
<HeaderBar title={title} headerStyle={[styles.header, animatedOpacity]} />
<GradientScrollView
onLayout={coverLayout.onLayout}
offset={artistCoverHeight}
@ -198,13 +141,9 @@ const ArtistView = React.memo<{ id: string; title: string }>(({ id, title }) =>
const artistCoverHeight = 350
const styles = StyleSheet.create({
headerText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontFamily: font.semiBold,
fontSize: 22,
color: colors.text.primary,
header: {
position: 'absolute',
zIndex: 1,
},
scroll: {
flex: 1,

View File

@ -1,4 +1,5 @@
import CoverArt from '@app/components/CoverArt'
import HeaderBar from '@app/components/HeaderBar'
import ImageGradientBackground from '@app/components/ImageGradientBackground'
import PressableOpacity from '@app/components/PressableOpacity'
import Star from '@app/components/Star'
@ -16,20 +17,18 @@ import { selectMusic } from '@app/state/music'
import { useStore } from '@app/state/store'
import { QueueContextType, selectTrackPlayer } from '@app/state/trackplayer'
import colors from '@app/styles/colors'
import dimensions from '@app/styles/dimensions'
import font from '@app/styles/font'
import formatDuration from '@app/util/formatDuration'
import Slider from '@react-native-community/slider'
import { useNavigation } from '@react-navigation/native'
import React, { useCallback, useEffect, useState } from 'react'
import { StatusBar, StyleSheet, Text, View } from 'react-native'
import { StyleSheet, Text, View } from 'react-native'
import { NativeStackScreenProps } from 'react-native-screens/native-stack'
import { RepeatMode, State } from 'react-native-track-player'
import IconFA from 'react-native-vector-icons/FontAwesome'
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
import Icon from 'react-native-vector-icons/Ionicons'
import IconMatCom from 'react-native-vector-icons/MaterialCommunityIcons'
import IconMat from 'react-native-vector-icons/MaterialIcons'
import Slider from '@react-native-community/slider'
function getContextName(type?: QueueContextType) {
switch (type) {
@ -54,10 +53,6 @@ const NowPlayingHeader = React.memo(() => {
let contextName = getContextName(queueContextType)
const back = useCallback(() => {
navigation.navigate('top')
}, [navigation])
const goToContext = useCallback(() => {
if (!queueContextType || !queueContextId || queueContextType === 'song') {
return
@ -67,61 +62,42 @@ const NowPlayingHeader = React.memo(() => {
}, [navigation, queueContextId, queueContextType, queueName])
return (
<View style={headerStyles.container}>
<PressableOpacity onPress={back} style={headerStyles.icons} ripple={true}>
<IconMat name="arrow-back" color="white" size={25} />
</PressableOpacity>
<View style={headerStyles.center}>
{contextName ? (
<Text numberOfLines={1} style={headerStyles.queueType}>
{contextName}
<HeaderBar
headerStyle={{ backgroundColor: 'transparent' }}
onMore={goToContext}
HeaderCenter={() => (
<View style={headerStyles.center}>
{contextName ? (
<Text numberOfLines={1} style={headerStyles.queueType}>
{contextName}
</Text>
) : (
<></>
)}
<Text numberOfLines={1} style={headerStyles.queueName}>
{queueName || 'Nothing playing...'}
</Text>
) : (
<></>
)}
<Text numberOfLines={1} style={headerStyles.queueName}>
{queueName || 'Nothing playing...'}
</Text>
</View>
<PressableOpacity
onPress={goToContext}
style={headerStyles.icons}
disabled={queueContextType === 'song'}
ripple={true}>
<IconMat name="more-vert" color="white" size={25} />
</PressableOpacity>
</View>
</View>
)}
/>
)
})
const headerStyles = StyleSheet.create({
container: {
height: dimensions.header,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
icons: {
height: 42,
width: 42,
marginHorizontal: 8,
},
center: {
flex: 1,
justifyContent: 'center',
},
queueType: {
fontFamily: font.regular,
fontSize: 14,
color: colors.text.primary,
// flex: 1,
textAlign: 'center',
},
queueName: {
fontFamily: font.bold,
fontSize: 16,
color: colors.text.primary,
// flex: 1,
textAlign: 'center',
},
})
@ -431,7 +407,7 @@ const NowPlayingView: React.FC<NowPlayingProps> = ({ navigation }) => {
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
// paddingTop: StatusBar.currentHeight,
},
content: {
flex: 1,