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
8367758113
commit
634ebe71e9
12
package-lock.json
generated
12
package-lock.json
generated
@ -25,7 +25,7 @@
|
||||
"react-native-fast-image": "^8.6.3",
|
||||
"react-native-file-system": "github:lyswhut/react-native-file-system#291582cd202053246458bf9376efe27fbb75afb6",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#35d7df1f68f19492749a9ea0541f02be77c0a675",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#fbf7c7d07475c6adb398b05653fa3cadc722d4ea",
|
||||
"react-native-navigation": "^7.37.2",
|
||||
"react-native-pager-view": "^6.2.3",
|
||||
"react-native-quick-base64": "^2.0.8",
|
||||
@ -9014,8 +9014,8 @@
|
||||
},
|
||||
"node_modules/react-native-local-media-metadata": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#35d7df1f68f19492749a9ea0541f02be77c0a675",
|
||||
"integrity": "sha512-Gbf8yuVQIWOAuJ4JQ5cRL9QNMePqsiPiSVw+e11ZfwKnZtpCtiwbgTixCjWpIcIyRsURNBz+3UJwQl2fPx6FWQ==",
|
||||
"resolved": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#fbf7c7d07475c6adb398b05653fa3cadc722d4ea",
|
||||
"integrity": "sha512-HIjzXi0t/70NoDn91wS/A0SiusPpKF1aJPXXZ1e8BMf5TyepOwzRWDezvz8tvymsb52caY7DesgUWS1Tv2m29A==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"example"
|
||||
@ -17217,9 +17217,9 @@
|
||||
}
|
||||
},
|
||||
"react-native-local-media-metadata": {
|
||||
"version": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#35d7df1f68f19492749a9ea0541f02be77c0a675",
|
||||
"integrity": "sha512-Gbf8yuVQIWOAuJ4JQ5cRL9QNMePqsiPiSVw+e11ZfwKnZtpCtiwbgTixCjWpIcIyRsURNBz+3UJwQl2fPx6FWQ==",
|
||||
"from": "react-native-local-media-metadata@github:lyswhut/react-native-local-media-metadata#35d7df1f68f19492749a9ea0541f02be77c0a675",
|
||||
"version": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#fbf7c7d07475c6adb398b05653fa3cadc722d4ea",
|
||||
"integrity": "sha512-HIjzXi0t/70NoDn91wS/A0SiusPpKF1aJPXXZ1e8BMf5TyepOwzRWDezvz8tvymsb52caY7DesgUWS1Tv2m29A==",
|
||||
"from": "react-native-local-media-metadata@github:lyswhut/react-native-local-media-metadata#fbf7c7d07475c6adb398b05653fa3cadc722d4ea",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-navigation": {
|
||||
|
@ -59,7 +59,7 @@
|
||||
"react-native-fast-image": "^8.6.3",
|
||||
"react-native-file-system": "github:lyswhut/react-native-file-system#291582cd202053246458bf9376efe27fbb75afb6",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#35d7df1f68f19492749a9ea0541f02be77c0a675",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#fbf7c7d07475c6adb398b05653fa3cadc722d4ea",
|
||||
"react-native-navigation": "^7.37.2",
|
||||
"react-native-pager-view": "^6.2.3",
|
||||
"react-native-quick-base64": "^2.0.8",
|
||||
|
@ -1,29 +1,24 @@
|
||||
// import { useEffect, useState } from 'react'
|
||||
import { Image, View } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import ImageBackground from '@/components/common/ImageBackground'
|
||||
import { useWindowSize } from '@/utils/hooks'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import playerState from '@/store/player/state'
|
||||
import settingState from '@/store/setting/state'
|
||||
import { useMemo } from 'react'
|
||||
import { scaleSizeAbsHR } from '@/utils/pixelRatio'
|
||||
import { defaultHeaders } from './common/Image'
|
||||
import SizeView from './SizeView'
|
||||
import { useBgPic } from '@/store/common/hook'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const formatUri = <T extends string | null>(url: T) => {
|
||||
return (typeof url == 'string' && url.startsWith('/')) ? `file://${url}` : url
|
||||
}
|
||||
|
||||
const BLUR_RADIUS = Math.max(scaleSizeAbsHR(24), 10)
|
||||
const BLUR_RADIUS = Math.max(scaleSizeAbsHR(18), 10)
|
||||
|
||||
export default ({ children }: Props) => {
|
||||
const theme = useTheme()
|
||||
const windowSize = useWindowSize()
|
||||
const [pic, setPic] = useState<string | null | undefined>(settingState.setting['theme.dynamicBg'] ? playerState.musicInfo.pic : null)
|
||||
const pic = useBgPic()
|
||||
// const [wh, setWH] = useState<{ width: number | string, height: number | string }>({ width: '100%', height: Dimensions.get('screen').height })
|
||||
|
||||
// 固定宽高度 防止弹窗键盘时大小改变导致背景被缩放
|
||||
@ -44,49 +39,6 @@ export default ({ children }: Props) => {
|
||||
// }
|
||||
// console.log('render page content')
|
||||
|
||||
useEffect(() => {
|
||||
let pic = playerState.musicInfo.pic
|
||||
let isUnmounted = false
|
||||
let isDynamicBg = settingState.setting['theme.dynamicBg']
|
||||
const handlePicUpdate = () => {
|
||||
if (playerState.musicInfo.pic && playerState.musicInfo.pic != playerState.loadErrorPicUrl) {
|
||||
// if (playerState.musicInfo.pic != playerState.loadErrorPicUrl) {
|
||||
// console.log('picUpdated', playerState.musicInfo.pic)
|
||||
pic = playerState.musicInfo.pic
|
||||
if (!isDynamicBg) return
|
||||
void Image.prefetch(formatUri(playerState.musicInfo.pic)).then(() => {
|
||||
if (pic != playerState.musicInfo.pic || isUnmounted) return
|
||||
setPic(playerState.musicInfo.pic)
|
||||
}).catch(() => {
|
||||
if (isUnmounted) return
|
||||
setPic(null)
|
||||
})
|
||||
}
|
||||
// } else {
|
||||
// if (!isDynamicBg) return
|
||||
// setPic(null)
|
||||
// }
|
||||
}
|
||||
const handleConfigUpdate = (keys: Array<keyof LX.AppSetting>, setting: Partial<LX.AppSetting>) => {
|
||||
if (!keys.includes('theme.dynamicBg')) return
|
||||
isDynamicBg = setting['theme.dynamicBg']!
|
||||
if (isDynamicBg) {
|
||||
if (playerState.musicInfo.pic) {
|
||||
pic = playerState.musicInfo.pic
|
||||
// console.log(pic)
|
||||
setPic(pic)
|
||||
}
|
||||
} else setPic(null)
|
||||
}
|
||||
global.state_event.on('playerMusicInfoChanged', handlePicUpdate)
|
||||
global.state_event.on('configUpdated', handleConfigUpdate)
|
||||
return () => {
|
||||
isUnmounted = true
|
||||
global.state_event.off('playerMusicInfoChanged', handlePicUpdate)
|
||||
global.state_event.off('configUpdated', handleConfigUpdate)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const themeComponent = useMemo(() => (
|
||||
<View style={{ flex: 1, overflow: 'hidden' }}>
|
||||
<ImageBackground
|
||||
@ -105,11 +57,11 @@ export default ({ children }: Props) => {
|
||||
<View style={{ flex: 1, overflow: 'hidden' }}>
|
||||
<ImageBackground
|
||||
style={{ position: 'absolute', left: 0, top: 0, height: windowSize.height, width: windowSize.width, backgroundColor: theme['c-content-background'] }}
|
||||
source={{ uri: formatUri(pic!), headers: defaultHeaders }}
|
||||
source={{ uri: pic!, headers: defaultHeaders }}
|
||||
resizeMode="cover"
|
||||
blurRadius={BLUR_RADIUS}
|
||||
>
|
||||
<View style={{ flex: 1, flexDirection: 'column', backgroundColor: theme['c-content-background'], opacity: 0.8 }}></View>
|
||||
<View style={{ flex: 1, flexDirection: 'column', backgroundColor: theme['c-content-background'], opacity: 0.76 }}></View>
|
||||
</ImageBackground>
|
||||
<View style={{ flex: 1, flexDirection: 'column' }}>
|
||||
{children}
|
||||
|
@ -94,3 +94,7 @@ export default forwardRef<View, ImageBackgroundProps>(({
|
||||
</View>
|
||||
)
|
||||
})
|
||||
|
||||
export const prefetch = async(url: string) => {
|
||||
return Image.prefetch(url)
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ export default ({ isHome }: { isHome: boolean }) => {
|
||||
|
||||
return (
|
||||
<TouchableOpacity onLongPress={handleLongPress} onPress={handlePress} activeOpacity={0.7} >
|
||||
<Image url={musicInfo.pic} cache={false} nativeID={NAV_SHEAR_NATIVE_IDS.playDetail_pic} style={styles.image} onError={handleError} />
|
||||
<Image url={musicInfo.pic} nativeID={NAV_SHEAR_NATIVE_IDS.playDetail_pic} style={styles.image} onError={handleError} />
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
@ -108,3 +108,7 @@ export const requestStoragePermission = async() => {
|
||||
await setSelectedManagedFolder(uri.path)
|
||||
return true
|
||||
}
|
||||
|
||||
export const setBgPic = (pic: string | null) => {
|
||||
commonActions.setBgPic(pic)
|
||||
}
|
||||
|
71
src/core/init/common.ts
Normal file
71
src/core/init/common.ts
Normal file
@ -0,0 +1,71 @@
|
||||
// import musicSdk from '@/utils/musicSdk'
|
||||
// import commonActions from '@/store/common/action'
|
||||
import playerState from '@/store/player/state'
|
||||
import { prefetch } from '@/components/common/ImageBackground'
|
||||
import { setBgPic } from '@/core/common'
|
||||
|
||||
// const handleUpdateSourceNmaes = () => {
|
||||
// const prefix = settingState.setting['common.sourceNameType'] == 'real' ? 'source_' : 'source_alias_'
|
||||
// const sourceNames: Record<LX.OnlineSource | 'all', string> = {
|
||||
// kw: 'kw',
|
||||
// tx: 'tx',
|
||||
// kg: 'kg',
|
||||
// mg: 'mg',
|
||||
// wy: 'wy',
|
||||
// // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
// all: global.i18n.t(prefix + 'all' as any),
|
||||
// }
|
||||
// for (const { id } of musicSdk.sources) {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
// sourceNames[id as LX.OnlineSource] = global.i18n.t(prefix + id as any)
|
||||
// }
|
||||
// commonActions.setSourceNames(sourceNames)
|
||||
// }
|
||||
const formatUri = <T extends string | null>(url: T) => {
|
||||
return (typeof url == 'string' && url.startsWith('/')) ? `file://${url}` : url
|
||||
}
|
||||
|
||||
export default async(setting: LX.AppSetting) => {
|
||||
// const handleConfigUpdated = (keys: Array<keyof LX.AppSetting>, setting: Partial<LX.AppSetting>) => {
|
||||
// // if (keys.includes('common.sourceNameType')) handleUpdateSourceNmaes()
|
||||
// handleConfigUpdate(keys, setting)
|
||||
// }
|
||||
|
||||
let pic = playerState.musicInfo.pic
|
||||
let isDynamicBg = setting['theme.dynamicBg']
|
||||
const handleUpdatePic = (pic: string) => {
|
||||
if (!pic) return
|
||||
const picUrl = formatUri(pic)
|
||||
void prefetch(picUrl).then(() => {
|
||||
if (pic != playerState.musicInfo.pic) return
|
||||
setBgPic(picUrl)
|
||||
})
|
||||
}
|
||||
const handlePicUpdate = () => {
|
||||
if (playerState.musicInfo.pic && playerState.musicInfo.pic != playerState.loadErrorPicUrl) {
|
||||
// if (playerState.musicInfo.pic != playerState.loadErrorPicUrl) {
|
||||
console.log('picUpdated', playerState.musicInfo.pic)
|
||||
pic = playerState.musicInfo.pic
|
||||
if (!isDynamicBg) return
|
||||
handleUpdatePic(pic)
|
||||
// .catch(() => {
|
||||
// if (pic != playerState.musicInfo.pic) return
|
||||
// setBgPic(null)
|
||||
// })
|
||||
}
|
||||
// } else {
|
||||
// if (!isDynamicBg) return
|
||||
// setPic(null)
|
||||
// }
|
||||
}
|
||||
const handleConfigUpdate = (keys: Array<keyof LX.AppSetting>, setting: Partial<LX.AppSetting>) => {
|
||||
if (!keys.includes('theme.dynamicBg')) return
|
||||
isDynamicBg = setting['theme.dynamicBg']!
|
||||
if (isDynamicBg) {
|
||||
if (pic) handleUpdatePic(pic)
|
||||
} else setBgPic(null)
|
||||
}
|
||||
handlePicUpdate()
|
||||
global.state_event.on('playerMusicInfoChanged', handlePicUpdate)
|
||||
global.state_event.on('configUpdated', handleConfigUpdate)
|
||||
}
|
@ -6,7 +6,7 @@ import initUserApi from './userApi'
|
||||
import initPlayer from './player'
|
||||
import dataInit from './dataInit'
|
||||
import initSync from './sync'
|
||||
// import syncSetting from './syncSetting'
|
||||
import initCommonState from './common'
|
||||
import { setApiSource } from '@/core/apiSource'
|
||||
import commonActions from '@/store/common/action'
|
||||
import settingState from '@/store/setting/state'
|
||||
@ -55,6 +55,10 @@ export default async() => {
|
||||
bootLog('Player inited.')
|
||||
await dataInit(setting)
|
||||
bootLog('Data inited.')
|
||||
await dataInit(setting)
|
||||
bootLog('Data inited.')
|
||||
await initCommonState(setting)
|
||||
bootLog('Common State inited.')
|
||||
|
||||
void initSync(setting)
|
||||
bootLog('Sync inited.')
|
||||
|
@ -1,28 +0,0 @@
|
||||
import musicSdk from '@/utils/musicSdk'
|
||||
import commonActions from '@/store/common/action'
|
||||
import settingState from '@/store/setting/state'
|
||||
|
||||
const handleUpdateSourceNmaes = () => {
|
||||
const prefix = settingState.setting['common.sourceNameType'] == 'real' ? 'source_' : 'source_alias_'
|
||||
const sourceNames: Record<LX.OnlineSource | 'all', string> = {
|
||||
kw: 'kw',
|
||||
tx: 'tx',
|
||||
kg: 'kg',
|
||||
mg: 'mg',
|
||||
wy: 'wy',
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
all: global.i18n.t(prefix + 'all' as any),
|
||||
}
|
||||
for (const { id } of musicSdk.sources) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
sourceNames[id as LX.OnlineSource] = global.i18n.t(prefix + id as any)
|
||||
}
|
||||
commonActions.setSourceNames(sourceNames)
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const handleConfigUpdated = (keys: Array<keyof LX.AppSetting>) => {
|
||||
if (keys.includes('common.sourceNameType')) handleUpdateSourceNmaes()
|
||||
}
|
||||
global.state_event.on('configUpdated', handleConfigUpdated)
|
||||
}
|
@ -40,6 +40,10 @@ export class StateEvent extends Event {
|
||||
this.emit('themeUpdated', theme)
|
||||
}
|
||||
|
||||
bgPicUpdated(bgPic: string | null) {
|
||||
this.emit('bgPicUpdated', bgPic)
|
||||
}
|
||||
|
||||
playerMusicInfoChanged(musicInfo: PlayerState['musicInfo']) {
|
||||
this.emit('playerMusicInfoChanged', musicInfo)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export default memo(({ componentId }: { componentId: string }) => {
|
||||
return (
|
||||
<View style={{ ...styles.container, height: contentHeight }}>
|
||||
<View style={{ ...styles.content, elevation: animated ? 3 : 0 }}>
|
||||
<Image url={musicInfo.pic} cache={false} nativeID={NAV_SHEAR_NATIVE_IDS.playDetail_pic} style={{
|
||||
<Image url={musicInfo.pic} nativeID={NAV_SHEAR_NATIVE_IDS.playDetail_pic} style={{
|
||||
width: imgWidth,
|
||||
height: imgWidth,
|
||||
borderRadius: 2,
|
||||
|
@ -35,7 +35,7 @@ export default ({ componentId }: { componentId: string }) => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={{ ...styles.content, elevation: animated ? 3 : 0 }}>
|
||||
<Image url={musicInfo.pic} cache={false} nativeID={NAV_SHEAR_NATIVE_IDS.playDetail_pic} style={style} />
|
||||
<Image url={musicInfo.pic} nativeID={NAV_SHEAR_NATIVE_IDS.playDetail_pic} style={style} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
@ -29,6 +29,10 @@ export default {
|
||||
setLastNavActiveId(id: InitState['navActiveId']) {
|
||||
state.lastNavActiveId = id
|
||||
},
|
||||
setBgPic(pic: string | null) {
|
||||
state.bgPic = pic
|
||||
global.state_event.bgPicUpdated(pic)
|
||||
},
|
||||
setSourceNames(names: InitState['sourceNames']) {
|
||||
state.sourceNames = names
|
||||
global.state_event.sourceNamesUpdated(names)
|
||||
|
@ -96,6 +96,19 @@ export const useNavActiveId = () => {
|
||||
return value
|
||||
}
|
||||
|
||||
export const useBgPic = () => {
|
||||
const [value, update] = useState(state.bgPic)
|
||||
|
||||
useEffect(() => {
|
||||
global.state_event.on('bgPicUpdated', update)
|
||||
return () => {
|
||||
global.state_event.off('bgPicUpdated', update)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
export const useSourceNames = () => {
|
||||
const [value, update] = useState(state.sourceNames)
|
||||
|
@ -8,6 +8,7 @@ export interface InitState {
|
||||
navActiveId: NAV_ID_Type
|
||||
lastNavActiveId: NAV_ID_Type
|
||||
sourceNames: Record<LX.OnlineSource | 'all', string>
|
||||
bgPic: string | null
|
||||
}
|
||||
|
||||
const initData = {}
|
||||
@ -19,6 +20,7 @@ const state: InitState = {
|
||||
navActiveId: 'nav_search',
|
||||
lastNavActiveId: 'nav_search',
|
||||
sourceNames: initData as InitState['sourceNames'],
|
||||
bgPic: null,
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user