mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
初步完善详情页
This commit is contained in:
parent
ce763bf420
commit
94f44a3762
4
index.js
4
index.js
@ -61,7 +61,7 @@ const init = () => {
|
||||
getPlayInfo().then(info => {
|
||||
if (!info) return
|
||||
global.restorePlayInfo = info
|
||||
if (info.listId != LIST_ID_PLAY_TEMP && info.listId != LIST_ID_PLAY_LATER) {
|
||||
if (info.listId != LIST_ID_PLAY_TEMP) {
|
||||
info.list = global.allList[info.listId]
|
||||
if (info.list) info.list = info.list.list
|
||||
}
|
||||
@ -76,7 +76,7 @@ const init = () => {
|
||||
})
|
||||
}
|
||||
|
||||
initNavigation(async() => {
|
||||
initNavigation(() => {
|
||||
init().then(() => {
|
||||
navigations.pushHomeScreen()
|
||||
SplashScreen.hide()
|
||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lx-music-mobile",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -35,6 +35,8 @@
|
||||
"collect_toplist": "Collection Toplist",
|
||||
"play_all": "Play all",
|
||||
"back": "Back",
|
||||
"name": "Name: {{name}}",
|
||||
"singer": "Artist: {{name}}",
|
||||
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
|
@ -35,6 +35,8 @@
|
||||
"collect_toplist": "收藏排行榜",
|
||||
"play_all": "播放全部",
|
||||
"back": "返回",
|
||||
"name": "歌曲名:{{name}}",
|
||||
"singer": "艺术家:{{name}}",
|
||||
|
||||
"cancel": "取消",
|
||||
"confirm": "确认",
|
||||
|
@ -3,14 +3,16 @@ import * as screenNames from './screenNames'
|
||||
import * as navigations from './navigation'
|
||||
|
||||
import registerScreens from './registerScreens'
|
||||
import { getStore } from '@/store'
|
||||
import { action as commonAction } from '@/store/modules/common'
|
||||
|
||||
// let unRegisterEvent
|
||||
let unRegisterEvent
|
||||
|
||||
const init = callback => {
|
||||
// Register all screens on launch
|
||||
registerScreens()
|
||||
|
||||
// if (unRegisterEvent) unRegisterEvent()
|
||||
if (unRegisterEvent) unRegisterEvent()
|
||||
|
||||
Navigation.setDefaultOptions({
|
||||
animations: {
|
||||
@ -19,9 +21,10 @@ const init = callback => {
|
||||
},
|
||||
},
|
||||
})
|
||||
// unRegisterEvent = Navigation.events().registerCommandListener((name, params) => {
|
||||
// console.log(name, params)
|
||||
// })
|
||||
unRegisterEvent = Navigation.events().registerScreenPoppedListener(({ componentId }) => {
|
||||
const store = getStore()
|
||||
store.dispatch(commonAction.removeComponentId(componentId))
|
||||
})
|
||||
Navigation.events().registerAppLaunchedListener(() => {
|
||||
console.log('Register app launched listener')
|
||||
callback()
|
||||
|
@ -9,43 +9,43 @@ import IsPlayHighQuality from './IsPlayHighQuality'
|
||||
import MaxCache from './MaxCache'
|
||||
import { useTranslation } from '@/plugins/i18n'
|
||||
|
||||
import DorpDownMenu from '@/components/common/DorpDownMenu'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
// import DorpDownMenu from '@/components/common/DorpDownMenu'
|
||||
// import { useGetter, useDispatch } from '@/store'
|
||||
|
||||
const playNextModes = [
|
||||
{ label: '列表循环', action: 'listLoop' },
|
||||
{ label: '列表随机', action: 'random' },
|
||||
{ label: '顺序播放', action: 'list' },
|
||||
{ label: '单曲循环', action: 'singleLoop' },
|
||||
]
|
||||
// const playNextModes = [
|
||||
// { label: '列表循环', action: 'listLoop' },
|
||||
// { label: '列表随机', action: 'random' },
|
||||
// { label: '顺序播放', action: 'list' },
|
||||
// { label: '单曲循环', action: 'singleLoop' },
|
||||
// ]
|
||||
|
||||
export default memo(() => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
// const [isShowModal, setIsShowModal] = useState(false)
|
||||
// const hideDialog = useCallback(() => setIsShowModal(false), [setIsShowModal])
|
||||
const togglePlayMethod = useGetter('common', 'togglePlayMethod')
|
||||
// const togglePlayMethod = useGetter('common', 'togglePlayMethod')
|
||||
|
||||
const togglePlayMethodName = useMemo(() => {
|
||||
const method = playNextModes.find(m => m.action == togglePlayMethod)
|
||||
return method ? method.label : '未知'
|
||||
}, [togglePlayMethod])
|
||||
const setPlayNextMode = useDispatch('common', 'setPlayNextMode')
|
||||
// const togglePlayMethodName = useMemo(() => {
|
||||
// const method = playNextModes.find(m => m.action == togglePlayMethod)
|
||||
// return method ? method.label : '未知'
|
||||
// }, [togglePlayMethod])
|
||||
// const setPlayNextMode = useDispatch('common', 'setPlayNextMode')
|
||||
// console.log(themeList)
|
||||
// const handlePress = id => {
|
||||
// setTheme(id)
|
||||
// // console.log(AppColors)
|
||||
// }
|
||||
const handleToggleMethodPress = ({ action }) => setPlayNextMode(action)
|
||||
// const handleToggleMethodPress = ({ action }) => setPlayNextMode(action)
|
||||
|
||||
return (
|
||||
<Section title={t('setting_play')}>
|
||||
<IsPlayHighQuality />
|
||||
<MaxCache />
|
||||
<View style={{ marginLeft: 15, marginBottom: 15 }}>
|
||||
{/* <View style={{ marginLeft: 15, marginBottom: 15 }}>
|
||||
<Text>播放歌曲切换方式</Text>
|
||||
<DorpDownMenu menus={playNextModes} onPress={handleToggleMethodPress}><Text style={{ padding: 10 }}>{togglePlayMethodName}</Text></DorpDownMenu>
|
||||
</View>
|
||||
</View> */}
|
||||
</Section>
|
||||
)
|
||||
})
|
||||
|
@ -23,10 +23,8 @@ export default ({ playNextModes }) => {
|
||||
// }, [setPlayNextMode, togglePlayMethod, playNextModes])
|
||||
|
||||
const btnPrev = useMemo(() => (
|
||||
<TouchableOpacity activeOpacity={0.5} onPress={playPrev}>
|
||||
<Text style={{ ...styles.cotrolBtn }}>
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={playPrev}>
|
||||
<Icon name='prevMusic' style={{ color: theme.secondary10 }} size={20} />
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
), [playPrev, theme])
|
||||
|
||||
@ -46,17 +44,13 @@ export default ({ playNextModes }) => {
|
||||
}
|
||||
}, [])
|
||||
const btnPlay = useMemo(() => (
|
||||
<TouchableOpacity activeOpacity={0.5} onPress={() => togglePlay(playStatus)}>
|
||||
<Text style={{ ...styles.cotrolBtn }}>
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={() => togglePlay(playStatus)}>
|
||||
<Icon name={playStatus == STATUS.playing ? 'pause' : 'play'} style={{ color: theme.secondary10 }} size={20} />
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
), [playStatus, theme, togglePlay])
|
||||
const btnNext = useMemo(() => (
|
||||
<TouchableOpacity activeOpacity={0.5} onPress={playNext}>
|
||||
<Text style={{ ...styles.cotrolBtn }}>
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={playNext}>
|
||||
<Icon name='nextMusic' style={{ color: theme.secondary10 }} size={20} />
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
), [playNext, theme])
|
||||
|
||||
@ -80,8 +74,8 @@ const styles = StyleSheet.create({
|
||||
cotrolBtn: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
lineHeight: 32,
|
||||
textAlign: 'center',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
|
||||
// backgroundColor: '#ccc',
|
||||
shadowOpacity: 1,
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import React, { memo, useMemo } from 'react'
|
||||
import { Text } from 'react-native'
|
||||
import { useGetter } from '@/store'
|
||||
import { STATUS } from '@/store/modules/player'
|
||||
import { useLrcPlay } from '@/plugins/lyric'
|
||||
|
||||
|
||||
export default () => {
|
||||
export default memo(() => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
const playStatus = useGetter('player', 'status')
|
||||
const statusText = useGetter('player', 'statusText')
|
||||
@ -18,7 +18,7 @@ export default () => {
|
||||
: statusText
|
||||
), [playStatus, statusText, text])
|
||||
return <Text numberOfLines={1} style={{ fontSize: 10, color: theme.normal10 }}>{status}</Text>
|
||||
}
|
||||
})
|
||||
|
||||
// const styles = StyleSheet.create({
|
||||
|
||||
|
@ -14,6 +14,7 @@ export default memo(({ playNextModes }) => {
|
||||
// const { onLayout, ...layout } = useLayout()
|
||||
const { keyboardShown } = useKeyboard()
|
||||
const theme = useGetter('common', 'theme')
|
||||
const componentIds = useGetter('common', 'componentIds')
|
||||
|
||||
const playerComponent = useMemo(() => (
|
||||
<View style={{ ...styles.container, backgroundColor: theme.primary, borderTopColor: theme.secondary10 }}>
|
||||
@ -33,7 +34,7 @@ export default memo(({ playNextModes }) => {
|
||||
|
||||
// console.log(layout)
|
||||
|
||||
return keyboardShown ? null : playerComponent
|
||||
return (keyboardShown || componentIds.playDetail) ? null : playerComponent
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -46,5 +46,6 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
img: {
|
||||
borderRadius: 4,
|
||||
// opacity: 0,
|
||||
},
|
||||
})
|
@ -0,0 +1,84 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect } from 'react'
|
||||
import { Text, StyleSheet, TouchableOpacity } from 'react-native'
|
||||
import Icon from '@/components/common/Icon'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
import { STATUS } from '@/store/modules/player'
|
||||
|
||||
|
||||
export default ({ playNextModes }) => {
|
||||
const playStatus = useGetter('player', 'status')
|
||||
const playNext = useDispatch('player', 'playNext')
|
||||
const playPrev = useDispatch('player', 'playPrev')
|
||||
// const playMusicInfo = useGetter('player', 'playMusicInfo')
|
||||
const pauseMusic = useDispatch('player', 'pauseMusic')
|
||||
const playMusic = useDispatch('player', 'playMusic')
|
||||
const theme = useGetter('common', 'theme')
|
||||
|
||||
// const togglePlayMethod = useGetter('common', 'togglePlayMethod')
|
||||
// const setPlayNextMode = useDispatch('common', 'setPlayNextMode')
|
||||
// const toggleNextPlayMode = useCallback(() => {
|
||||
// let index = playNextModes.indexOf(togglePlayMethod)
|
||||
// if (++index >= playNextModes.length) index = -1
|
||||
// setPlayNextMode(playNextModes[index] || '')
|
||||
// }, [setPlayNextMode, togglePlayMethod, playNextModes])
|
||||
|
||||
const btnPrev = useMemo(() => (
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={playPrev}>
|
||||
<Icon name='prevMusic' style={{ color: theme.secondary10 }} size={30} />
|
||||
</TouchableOpacity>
|
||||
), [playPrev, theme])
|
||||
|
||||
const togglePlay = useCallback(playStatus => {
|
||||
switch (playStatus) {
|
||||
case STATUS.playing:
|
||||
pauseMusic()
|
||||
break
|
||||
case STATUS.pause:
|
||||
case STATUS.stop:
|
||||
case STATUS.none:
|
||||
playMusic()
|
||||
break
|
||||
// default:
|
||||
// playMusic(playMusicInfo)
|
||||
// break
|
||||
}
|
||||
}, [])
|
||||
const btnPlay = useMemo(() => (
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={() => togglePlay(playStatus)}>
|
||||
<Icon name={playStatus == STATUS.playing ? 'pause' : 'play'} style={{ color: theme.secondary10 }} size={30} />
|
||||
</TouchableOpacity>
|
||||
), [playStatus, theme, togglePlay])
|
||||
const btnNext = useMemo(() => (
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={playNext}>
|
||||
<Icon name='nextMusic' style={{ color: theme.secondary10 }} size={30} />
|
||||
</TouchableOpacity>
|
||||
), [playNext, theme])
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <TouchableOpacity activeOpacity={0.5} onPress={toggleNextPlayMode}>
|
||||
<Text style={{ ...styles.cotrolBtn }}>
|
||||
<Icon name={playModeIcon} style={{ color: theme.secondary10 }} size={18} />
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
*/}
|
||||
{btnPrev}
|
||||
{btnPlay}
|
||||
{btnNext}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
cotrolBtn: {
|
||||
width: 42,
|
||||
height: 42,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
|
||||
// backgroundColor: '#ccc',
|
||||
shadowOpacity: 1,
|
||||
textShadowRadius: 1,
|
||||
},
|
||||
})
|
@ -0,0 +1,47 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect, useState, useRef } from 'react'
|
||||
import { Text, StyleSheet, TouchableOpacity } from 'react-native'
|
||||
import Icon from '@/components/common/Icon'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
import MusicAddModal from '@/components/MusicAddModal'
|
||||
|
||||
|
||||
export default memo(() => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
const [visibleMusicAddModal, setVisibleMusicAddModal] = useState(false)
|
||||
const playMusicInfo = useGetter('player', 'playMusicInfo')
|
||||
const selectedDataRef = useRef()
|
||||
const hideMusicAddModal = () => {
|
||||
setVisibleMusicAddModal(false)
|
||||
}
|
||||
|
||||
const handleShowMusicAddModal = () => {
|
||||
selectedDataRef.current = playMusicInfo.musicInfo
|
||||
setVisibleMusicAddModal(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={handleShowMusicAddModal}>
|
||||
<Icon name="add-music" style={{ color: theme.secondary10 }} size={24} />
|
||||
</TouchableOpacity>
|
||||
<MusicAddModal
|
||||
visible={visibleMusicAddModal}
|
||||
hideModal={hideMusicAddModal}
|
||||
musicInfo={selectedDataRef.current} />
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
cotrolBtn: {
|
||||
marginLeft: 5,
|
||||
width: 32,
|
||||
height: 32,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
|
||||
// backgroundColor: '#ccc',
|
||||
shadowOpacity: 1,
|
||||
textShadowRadius: 1,
|
||||
},
|
||||
})
|
@ -0,0 +1,65 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect } from 'react'
|
||||
import { Text, StyleSheet, TouchableOpacity } from 'react-native'
|
||||
import Icon from '@/components/common/Icon'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
|
||||
const playNextModes = [
|
||||
'listLoop',
|
||||
'random',
|
||||
'list',
|
||||
'singleLoop',
|
||||
]
|
||||
|
||||
export default memo(() => {
|
||||
const togglePlayMethod = useGetter('common', 'togglePlayMethod')
|
||||
const theme = useGetter('common', 'theme')
|
||||
const setPlayNextMode = useDispatch('common', 'setPlayNextMode')
|
||||
|
||||
const toggleNextPlayMode = () => {
|
||||
let index = playNextModes.indexOf(togglePlayMethod)
|
||||
if (++index >= playNextModes.length) index = -1
|
||||
setPlayNextMode(playNextModes[index] || '')
|
||||
}
|
||||
|
||||
const playModeIcon = useMemo(() => {
|
||||
let playModeIcon = null
|
||||
switch (togglePlayMethod) {
|
||||
case 'listLoop':
|
||||
playModeIcon = 'list-loop'
|
||||
break
|
||||
case 'random':
|
||||
playModeIcon = 'list-random'
|
||||
break
|
||||
case 'list':
|
||||
playModeIcon = 'list-order'
|
||||
break
|
||||
case 'singleLoop':
|
||||
playModeIcon = 'single-loop'
|
||||
break
|
||||
default:
|
||||
playModeIcon = 'single'
|
||||
break
|
||||
}
|
||||
return playModeIcon
|
||||
}, [togglePlayMethod])
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={{ ...styles.cotrolBtn }} activeOpacity={0.5} onPress={toggleNextPlayMode}>
|
||||
<Icon name={playModeIcon} style={{ color: theme.secondary10 }} size={24} />
|
||||
</TouchableOpacity>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
cotrolBtn: {
|
||||
marginLeft: 5,
|
||||
width: 32,
|
||||
height: 32,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
|
||||
// backgroundColor: '#ccc',
|
||||
shadowOpacity: 1,
|
||||
textShadowRadius: 1,
|
||||
},
|
||||
})
|
@ -0,0 +1,24 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect } from 'react'
|
||||
import { View, StyleSheet } from 'react-native'
|
||||
import PlayModeBtn from './PlayModeBtn'
|
||||
import MusicAddBtn from './MusicAddBtn'
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<PlayModeBtn />
|
||||
<MusicAddBtn />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexShrink: 0,
|
||||
flexGrow: 0,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
// backgroundColor: 'rgba(0,0,0,0.1)',
|
||||
},
|
||||
})
|
52
src/screens/PlayDetail/Player/Player/components/PlayInfo.js
Normal file
52
src/screens/PlayDetail/Player/Player/components/PlayInfo.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect } from 'react'
|
||||
import { Text, StyleSheet, View } from 'react-native'
|
||||
import { usePlayTime } from '@/utils/hooks'
|
||||
import { useGetter } from '@/store'
|
||||
|
||||
import Progress from '@/components/player/Progress'
|
||||
import Status from './Status'
|
||||
|
||||
const PlayTimeCurrent = ({ timeStr }) => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
// console.log(timeStr)
|
||||
return <Text style={{ fontSize: 14, color: theme.normal10 }}>{timeStr}</Text>
|
||||
}
|
||||
|
||||
const PlayTimeMax = memo(({ timeStr }) => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
return <Text style={{ fontSize: 14, color: theme.normal10 }}>{timeStr}</Text>
|
||||
})
|
||||
|
||||
export default () => {
|
||||
const { curTimeStr, maxTimeStr, progress, bufferedProgress, duration } = usePlayTime()
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={styles.progress}><Progress progress={progress} bufferedProgress={bufferedProgress} duration={duration} /></View>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<View style={{ flexGrow: 1, flexShrink: 1, paddingRight: 5 }} >
|
||||
<Status />
|
||||
</View>
|
||||
<View style={{ flexGrow: 0, flexShrink: 0, flexDirection: 'row' }} >
|
||||
<PlayTimeCurrent timeStr={curTimeStr} />
|
||||
<Text style={{ fontSize: 14 }}> / </Text>
|
||||
<PlayTimeMax timeStr={maxTimeStr} />
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
progress: {
|
||||
flexGrow: 1,
|
||||
flexShrink: 0,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
// height:
|
||||
// position: 'absolute',
|
||||
// width: '100%',
|
||||
// top: 0,
|
||||
},
|
||||
})
|
25
src/screens/PlayDetail/Player/Player/components/Status.js
Normal file
25
src/screens/PlayDetail/Player/Player/components/Status.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { memo, useMemo } from 'react'
|
||||
import { Text } from 'react-native'
|
||||
import { useGetter } from '@/store'
|
||||
import { STATUS } from '@/store/modules/player'
|
||||
|
||||
|
||||
export default memo(() => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
const playStatus = useGetter('player', 'status')
|
||||
const statusText = useGetter('player', 'statusText')
|
||||
const status = useMemo(() => {
|
||||
switch (playStatus) {
|
||||
case STATUS.playing:
|
||||
case STATUS.pause:
|
||||
case STATUS.stop:
|
||||
return ''
|
||||
default: return statusText
|
||||
}
|
||||
}, [playStatus, statusText])
|
||||
return <Text numberOfLines={1} style={{ fontSize: 13, color: theme.normal10 }}>{status}</Text>
|
||||
})
|
||||
|
||||
// const styles = StyleSheet.create({
|
||||
|
||||
// })
|
35
src/screens/PlayDetail/Player/Player/components/Title.js
Normal file
35
src/screens/PlayDetail/Player/Player/components/Title.js
Normal file
@ -0,0 +1,35 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect } from 'react'
|
||||
import { Text, View, StyleSheet } from 'react-native'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
import { useTranslation } from '@/plugins/i18n'
|
||||
|
||||
export default () => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
const playMusicInfo = useGetter('player', 'playMusicInfo')
|
||||
const { t } = useTranslation()
|
||||
const titleInfo = useMemo(() => {
|
||||
const info = {
|
||||
name: '',
|
||||
singer: '',
|
||||
}
|
||||
if (playMusicInfo) {
|
||||
info.name = t('name', { name: playMusicInfo.musicInfo.name })
|
||||
info.singer = t('singer', { name: playMusicInfo.musicInfo.singer })
|
||||
}
|
||||
return info
|
||||
}, [playMusicInfo, t])
|
||||
// console.log(playMusicInfo)
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={{ width: '100%', fontSize: 14, color: theme.normal }} numberOfLines={2}>{titleInfo.name}</Text>
|
||||
<Text style={{ width: '100%', fontSize: 14, color: theme.normal }} numberOfLines={2}>{titleInfo.singer}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexShrink: 1,
|
||||
flexGrow: 1,
|
||||
},
|
||||
})
|
69
src/screens/PlayDetail/Player/Player/index.js
Normal file
69
src/screens/PlayDetail/Player/Player/index.js
Normal file
@ -0,0 +1,69 @@
|
||||
import React, { useCallback, memo, useMemo, useEffect } from 'react'
|
||||
import { View, Text, StyleSheet } from 'react-native'
|
||||
import { useLayout, useKeyboard } from '@/utils/hooks'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
import { BorderWidths } from '@/theme'
|
||||
|
||||
import Title from './components/Title'
|
||||
import MoreBtn from './components/MoreBtn'
|
||||
import PlayInfo from './components/PlayInfo'
|
||||
import ControlBtn from './components/ControlBtn'
|
||||
|
||||
|
||||
export default memo(({ playNextModes }) => {
|
||||
// const { onLayout, ...layout } = useLayout()
|
||||
const theme = useGetter('common', 'theme')
|
||||
|
||||
return (
|
||||
<View style={{ ...styles.container, backgroundColor: theme.primary }}>
|
||||
<View style={{ ...styles.info }}>
|
||||
<Title />
|
||||
<MoreBtn />
|
||||
</View>
|
||||
<View style={styles.status}>
|
||||
<PlayInfo />
|
||||
</View>
|
||||
<View style={styles.control}>
|
||||
<ControlBtn playNextModes={playNextModes} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
// paddingTop: progressContentPadding,
|
||||
// marginTop: -progressContentPadding,
|
||||
// backgroundColor: 'rgba(0, 0, 0, .1)',
|
||||
padding: 15,
|
||||
// backgroundColor: AppColors.primary,
|
||||
// backgroundColor: 'red',
|
||||
},
|
||||
info: {
|
||||
flexDirection: 'row',
|
||||
paddingBottom: 10,
|
||||
},
|
||||
status: {
|
||||
flexDirection: 'column',
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
paddingLeft: 5,
|
||||
justifyContent: 'space-evenly',
|
||||
},
|
||||
control: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-evenly',
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
paddingLeft: '15%',
|
||||
paddingRight: '15%',
|
||||
paddingTop: '10%',
|
||||
paddingBottom: '8%',
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
},
|
||||
})
|
@ -1,10 +1,10 @@
|
||||
import React, { useEffect, useCallback } from 'react'
|
||||
import { View, StyleSheet } from 'react-native'
|
||||
|
||||
import Header from './components/Header'
|
||||
import Header from '../components/Header'
|
||||
// import Aside from './components/Aside'
|
||||
// import Main from './components/Main'
|
||||
// import FooterPlayer from './components/FooterPlayer'
|
||||
import Player from './Player'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
import PagerView from 'react-native-pager-view'
|
||||
import Pic from './Pic'
|
||||
@ -32,7 +32,7 @@ export default () => {
|
||||
</View>
|
||||
</PagerView>
|
||||
<View style={styles.player}>
|
||||
|
||||
<Player />
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
|
@ -1,59 +1,20 @@
|
||||
import React, { useEffect, useCallback } from 'react'
|
||||
import { View, StyleSheet } from 'react-native'
|
||||
|
||||
import Header from './components/Header'
|
||||
// import Aside from './components/Aside'
|
||||
// import Main from './components/Main'
|
||||
// import FooterPlayer from './components/FooterPlayer'
|
||||
import { useGetter, useDispatch } from '@/store'
|
||||
import PagerView from 'react-native-pager-view'
|
||||
import Pic from './Pic'
|
||||
|
||||
import Player from './Player'
|
||||
|
||||
export default (props) => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
// const theme = useGetter('common', 'theme')
|
||||
const setComponentId = useDispatch('common', 'setComponentId')
|
||||
useEffect(() => {
|
||||
setComponentId({ name: 'playDetail', id: props.componentId })
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const onPageScrollStateChanged = useCallback(({ nativeEvent }) => {
|
||||
// console.log(nativeEvent)
|
||||
if (nativeEvent.pageScrollState != 'idle') return
|
||||
console.log(nativeEvent.pageScrollState)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header componentId={props.componentId} />
|
||||
<View style={{ flex: 1, flexDirection: 'column', height: '100%', backgroundColor: theme.primary }}>
|
||||
<PagerView
|
||||
// onPageSelected={onPageSelected}
|
||||
onPageScrollStateChanged={onPageScrollStateChanged}
|
||||
style={styles.pagerView}
|
||||
>
|
||||
<View collapsable={false} key="1" style={styles.pageStyle}>
|
||||
<Pic />
|
||||
</View>
|
||||
</PagerView>
|
||||
<View style={styles.player}>
|
||||
|
||||
</View>
|
||||
</View>
|
||||
<Player />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
pagerView: {
|
||||
flex: 1,
|
||||
},
|
||||
player: {
|
||||
flex: 0,
|
||||
},
|
||||
})
|
||||
|
@ -13,6 +13,7 @@ import { VERSION_STATUS } from '@/config/constant'
|
||||
export const TYPES = {
|
||||
updateSetting: null,
|
||||
setComponentId: null,
|
||||
removeComponentId: null,
|
||||
setNavActiveIndex: null,
|
||||
setNavScreenName: null,
|
||||
setPlayNextMode: null,
|
||||
@ -106,6 +107,10 @@ export const setComponentId = data => ({
|
||||
type: TYPES.setComponentId,
|
||||
payload: data,
|
||||
})
|
||||
export const removeComponentId = id => ({
|
||||
type: TYPES.removeComponentId,
|
||||
payload: id,
|
||||
})
|
||||
|
||||
export const setNavActiveIndex = index => ({
|
||||
type: TYPES.setNavActiveIndex,
|
||||
|
@ -65,6 +65,19 @@ const mutations = {
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.removeComponentId](state, removeId) {
|
||||
const newComponentIds = { ...state.componentIds }
|
||||
for (const [name, id] of Object.entries(state.componentIds)) {
|
||||
if (id == removeId) {
|
||||
newComponentIds[name] = null
|
||||
break
|
||||
}
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
componentIds: newComponentIds,
|
||||
}
|
||||
},
|
||||
[TYPES.setNavActiveIndex](state, index) {
|
||||
if (index === state.nav.activeIndex) return state
|
||||
return {
|
||||
|
@ -15,17 +15,13 @@ import {
|
||||
destroy as msDestroy,
|
||||
} from '@/plugins/player/utils'
|
||||
import { getRandom } from '@/utils'
|
||||
import { getMusicUrl, saveMusicUrl, getLyric, saveLyric, assertApiSupport, savePlayInfo } from '@/utils/tools'
|
||||
import { setData } from '@/plugins/storage'
|
||||
import { storageDataPrefix } from '@/config'
|
||||
import { getMusicUrl, saveMusicUrl, getLyric, saveLyric, assertApiSupport, savePlayInfo, saveList } from '@/utils/tools'
|
||||
import { playInfo as playInfoGetter } from './getter'
|
||||
import { play as lrcPlay, setLyric, pause as lrcPause } from '@/plugins/lyric'
|
||||
import { action as listAction } from '@/store/modules/list'
|
||||
import { LIST_ID_PLAY_LATER } from '@/config/constant'
|
||||
// import { defaultList } from '../list/getter'
|
||||
|
||||
const listPrefix = storageDataPrefix.list
|
||||
|
||||
export const TYPES = {
|
||||
setPic: null,
|
||||
setList: null,
|
||||
@ -474,7 +470,7 @@ export const getPic = musicInfo => (dispatch, getState) => {
|
||||
// picRequest = null
|
||||
dispatch({ type: TYPES.setPic, payload: { musicInfo, url } })
|
||||
const state = getState()
|
||||
if (state.player.listInfo.id) setData(listPrefix + state.player.listInfo.id, global.allList[state.player.listInfo.id])
|
||||
if (state.player.listInfo.id) saveList(global.allList[state.player.listInfo.id])
|
||||
}).catch(err => {
|
||||
// picRequest = null
|
||||
return Promise.reject(err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user