mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-03 06:52:09 +08:00
145 lines
4.5 KiB
TypeScript
145 lines
4.5 KiB
TypeScript
import { forwardRef, memo, useImperativeHandle, useState } from 'react'
|
|
import { View } from 'react-native'
|
|
import { BorderWidths } from '@/theme'
|
|
import ButtonBar from './ActionBar'
|
|
import { useNavigationComponentDidAppear } from '@/navigation'
|
|
import { NAV_SHEAR_NATIVE_IDS } from '@/config/constant'
|
|
import { scaleSizeW } from '@/utils/pixelRatio'
|
|
import { useTheme } from '@/store/theme/hook'
|
|
import Text, { AnimatedText } from '@/components/common/Text'
|
|
import { createStyle } from '@/utils/tools'
|
|
import StatusBar from '@/components/common/StatusBar'
|
|
import Image from '@/components/common/Image'
|
|
import { useListInfo } from './state'
|
|
import { useAnimateOnecNumber } from '@/utils/hooks/useAnimateNumber'
|
|
|
|
const IMAGE_WIDTH = scaleSizeW(70)
|
|
|
|
const CountText = memo(({ count }: { count: string }) => {
|
|
const [animFade] = useAnimateOnecNumber(0, 1, 250, false)
|
|
const [animTranslateY] = useAnimateOnecNumber(10, 0, 250, false)
|
|
return (
|
|
<AnimatedText style={{
|
|
...styles.playCount,
|
|
opacity: animFade,
|
|
transform: [
|
|
{ translateY: animTranslateY },
|
|
],
|
|
}} numberOfLines={ 1 }>{count}</AnimatedText>
|
|
)
|
|
}, (prevProps, nextProps) => {
|
|
return true
|
|
})
|
|
|
|
const Pic = ({ componentId, playCount, imgUrl }: {
|
|
componentId: string
|
|
playCount: string
|
|
imgUrl?: string
|
|
}) => {
|
|
const [animated, setAnimated] = useState(false)
|
|
const info = useListInfo()
|
|
|
|
useNavigationComponentDidAppear(componentId, () => {
|
|
setAnimated(true)
|
|
})
|
|
|
|
return (
|
|
<View style={{ ...styles.listItemImg, width: IMAGE_WIDTH, height: IMAGE_WIDTH }}>
|
|
<Image nativeID={`${NAV_SHEAR_NATIVE_IDS.songlistDetail_pic}_to_${info.id}`} url={imgUrl} style={{ flex: 1, borderRadius: 4 }} />
|
|
{
|
|
playCount && animated ? <CountText count={playCount} /> : null
|
|
}
|
|
</View>
|
|
)
|
|
}
|
|
|
|
export interface HeaderProps {
|
|
componentId: string
|
|
}
|
|
|
|
export interface HeaderType {
|
|
setInfo: (info: DetailInfo) => void
|
|
}
|
|
export interface DetailInfo {
|
|
name: string
|
|
desc: string
|
|
playCount: string
|
|
imgUrl?: string
|
|
}
|
|
|
|
export default forwardRef<HeaderType, HeaderProps>(({ componentId }: { componentId: string }, ref) => {
|
|
const theme = useTheme()
|
|
const info = useListInfo()
|
|
const [detailInfo, setDetailInfo] = useState<DetailInfo>({ name: '', desc: '', playCount: '', imgUrl: info.img })
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
setInfo(info) {
|
|
setDetailInfo(info)
|
|
},
|
|
}), [])
|
|
|
|
return (
|
|
<View style={{ ...styles.container, paddingTop: StatusBar.currentHeight, borderBottomColor: theme['c-border-background'] }}>
|
|
<View style={{ flexDirection: 'row', flexGrow: 0, flexShrink: 0, padding: 10 }}>
|
|
<Pic componentId={componentId} playCount={detailInfo.playCount} imgUrl={detailInfo.imgUrl} />
|
|
<View style={{ flexDirection: 'column', flexGrow: 1, flexShrink: 1, paddingLeft: 5 }} nativeID={NAV_SHEAR_NATIVE_IDS.songlistDetail_title}>
|
|
<Text size={14} numberOfLines={ 1 }>{detailInfo.name}</Text>
|
|
<View style={{ flexGrow: 0, flexShrink: 1 }}>
|
|
<Text size={13} color={theme['c-font-label']} numberOfLines={ 4 }>{detailInfo.desc}</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
<ButtonBar />
|
|
{/* <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
<View style={{ flexGrow: 0, flexShrink: 1, paddingTop: 5, paddingRight: 5 }}>
|
|
<Text style={{ fontSize: 12, color: AppColors.normal20 }} numberOfLines={ 1 }>{playCount || '-'}</Text>
|
|
<Text style={{ fontSize: 12, color: AppColors.normal30 }} numberOfLines={ 1 }>{this.props.selectListInfo.author || this.props.listDetailData.info.author}</Text>
|
|
</View>
|
|
</View> */}
|
|
</View>
|
|
)
|
|
})
|
|
|
|
const styles = createStyle({
|
|
container: {
|
|
flexDirection: 'column',
|
|
flexWrap: 'nowrap',
|
|
borderBottomWidth: BorderWidths.normal,
|
|
},
|
|
listItemImg: {
|
|
// backgroundColor: '#eee',
|
|
flexGrow: 0,
|
|
flexShrink: 0,
|
|
overflow: 'hidden',
|
|
// width: 70,
|
|
// height: 70,
|
|
// ...Platform.select({
|
|
// ios: {
|
|
// shadowColor: '#000',
|
|
// shadowOffset: {
|
|
// width: 0,
|
|
// height: 1,
|
|
// },
|
|
// shadowOpacity: 0.20,
|
|
// shadowRadius: 1.41,
|
|
// },
|
|
// android: {
|
|
// elevation: 2,
|
|
// },
|
|
// }),
|
|
},
|
|
playCount: {
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
left: 0,
|
|
width: '100%',
|
|
fontSize: 12,
|
|
paddingLeft: 3,
|
|
paddingRight: 3,
|
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
color: '#fff',
|
|
borderBottomLeftRadius: 4,
|
|
borderBottomRightRadius: 4,
|
|
},
|
|
})
|