From 47a1657bc2e5d87803128d7cbe0b3d785aac5e0a Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 17 Dec 2023 16:45:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81=E8=83=8C?= =?UTF-8?q?=E6=99=AF=EF=BC=8C=E9=BB=98=E8=AE=A4=E5=85=B3=E9=97=AD=EF=BC=8C?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E5=90=8E=E5=B0=86=E4=BD=BF=E7=94=A8=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E6=AD=8C=E6=9B=B2=E5=B0=81=E9=9D=A2=E5=81=9AAPP?= =?UTF-8?q?=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/components/PageContent.tsx | 70 +++++++++++++++++-- src/components/common/ImageBackground.tsx | 25 +++---- src/config/defaultSetting.ts | 1 + src/lang/en_us.json | 1 + src/lang/zh_cn.json | 1 + .../Setting/settings/Theme/IsDynamicBg.tsx | 30 ++++++++ .../Views/Setting/settings/Theme/Theme.tsx | 8 +-- .../Views/Setting/settings/Theme/index.tsx | 2 + src/types/app_setting.d.ts | 5 ++ src/types/theme.d.ts | 5 +- 11 files changed, 126 insertions(+), 23 deletions(-) create mode 100644 src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx diff --git a/publish/changeLog.md b/publish/changeLog.md index cc58668aa..f990dc013 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -4,6 +4,7 @@ - 新增长按收藏列表名自动跳转列表顶部的功能 - 新增实验性的添加本地歌曲到我的收藏支持,与PC端类似,在我的收藏的列表菜单中选择歌曲目录,将添加所选目录下的所有歌曲,目前支持mp3/flac/ogg/wav格式 - 新增歌曲标签编辑功能,允许编辑本地源且文件歌曲存在的歌曲标签信息 +- 新增动态背景,默认关闭,启用后将使用当前歌曲封面做APP背景 ### 优化 diff --git a/src/components/PageContent.tsx b/src/components/PageContent.tsx index 50cb72e16..4c5e27aab 100644 --- a/src/components/PageContent.tsx +++ b/src/components/PageContent.tsx @@ -1,8 +1,11 @@ // import { useEffect, useState } from 'react' -import { View } from 'react-native' +import { Image, 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' interface Props { children: React.ReactNode @@ -12,6 +15,7 @@ interface Props { export default ({ children }: Props) => { const theme = useTheme() const windowSize = useWindowSize() + const [pic, setPic] = useState(settingState.setting['theme.dynamicBg'] ? playerState.musicInfo.pic : null) // const [wh, setWH] = useState<{ width: number | string, height: number | string }>({ width: '100%', height: Dimensions.get('screen').height }) // 固定宽高度 防止弹窗键盘时大小改变导致背景被缩放 @@ -32,11 +36,52 @@ export default ({ children }: Props) => { // } // console.log('render page content') - return ( + 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) { + console.log('picUpdated', playerState.musicInfo.pic) + pic = playerState.musicInfo.pic + if (!isDynamicBg) return + void Image.prefetch(playerState.musicInfo.pic).then(() => { + if (pic != playerState.musicInfo.pic || isUnmounted) return + setPic(playerState.musicInfo.pic) + }).catch(() => { + if (isUnmounted) return + setPic(null) + }) + } else if (playerState.loadErrorPicUrl == pic) { + if (!isDynamicBg) return + setPic(null) + } + } + const handleConfigUpdate = (keys: Array, setting: Partial) => { + 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(() => ( @@ -44,5 +89,22 @@ export default ({ children }: Props) => { {children} - ) + ), [children, theme, windowSize.height, windowSize.width]) + const picComponent = useMemo(() => ( + + + + + + {children} + + + ), [children, pic, theme, windowSize.height, windowSize.width]) + + return pic ? picComponent : themeComponent } diff --git a/src/components/common/ImageBackground.tsx b/src/components/common/ImageBackground.tsx index 6bb9f1409..32160f059 100644 --- a/src/components/common/ImageBackground.tsx +++ b/src/components/common/ImageBackground.tsx @@ -13,9 +13,9 @@ import { forwardRef } from 'react' import { View, StyleSheet, + Image, } from 'react-native' -import type { ViewProps } from 'react-native' -import Image, { type ImageProps } from './Image' +import type { ImageBackgroundProps as _ImageBackgroundProps } from 'react-native' /** @@ -45,32 +45,32 @@ import Image, { type ImageProps } from './Image' export type ImageBackgroundType = View -export type ImageSourceType = string | number - -export interface ImageBackgroundProps extends Omit { - style: ViewProps['style'] - imageStyle?: ImageProps['style'] +export interface ImageBackgroundProps extends Omit<_ImageBackgroundProps, 'source'> { + source?: _ImageBackgroundProps['source'] | null } -export default forwardRef(({ +export default forwardRef(({ children, style, imageStyle, - url, + imageRef, + importantForAccessibility, + source, ...props }, ref) => { const flattenedStyle = StyleSheet.flatten(style) return ( { - url == null ? null : ( + source == null ? null : ( (({ }, imageStyle, ]} + ref={imageRef} /> ) } diff --git a/src/config/defaultSetting.ts b/src/config/defaultSetting.ts index f6005d3c4..4ff2748e9 100644 --- a/src/config/defaultSetting.ts +++ b/src/config/defaultSetting.ts @@ -70,6 +70,7 @@ const defaultSetting: LX.AppSetting = { 'theme.lightId': 'green', 'theme.darkId': 'black', 'theme.hideBgDark': false, + 'theme.dynamicBg': false, } diff --git a/src/lang/en_us.json b/src/lang/en_us.json index 3ffac5d4a..d5efd338d 100644 --- a/src/lang/en_us.json +++ b/src/lang/en_us.json @@ -247,6 +247,7 @@ "setting_basic_startup_auto_play": "Play music automatically after startup", "setting_basic_theme": "Theme", "setting_basic_theme_auto_theme": "Follow the system light and dark mode to switch themes", + "setting_basic_theme_dynamic_bg": "Use dynamic backgrounds", "setting_basic_theme_hide_bg_dark": "Hide black theme", "setting_basic_theme_more_btn_show": "Expand themes", "setting_dislike_list_input_tip": "song name@artist name\nSong name\n@ singer name", diff --git a/src/lang/zh_cn.json b/src/lang/zh_cn.json index 44799df29..280e3fc1e 100644 --- a/src/lang/zh_cn.json +++ b/src/lang/zh_cn.json @@ -247,6 +247,7 @@ "setting_basic_startup_auto_play": "启动后自动播放音乐", "setting_basic_theme": "主题颜色", "setting_basic_theme_auto_theme": "跟随系统亮、暗模式切换主题", + "setting_basic_theme_dynamic_bg": "使用动态背景", "setting_basic_theme_hide_bg_dark": "隐藏黑色主题背景", "setting_basic_theme_more_btn_show": "更多主题", "setting_dislike_list_input_tip": "歌曲名@歌手名\n歌曲名\n@歌手名", diff --git a/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx b/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx new file mode 100644 index 000000000..cc4a1b586 --- /dev/null +++ b/src/screens/Home/Views/Setting/settings/Theme/IsDynamicBg.tsx @@ -0,0 +1,30 @@ +import { memo } from 'react' +import { View } from 'react-native' + +import CheckBoxItem from '../../components/CheckBoxItem' +import { createStyle } from '@/utils/tools' +import { useI18n } from '@/lang' +import { updateSetting } from '@/core/common' +import { useSettingValue } from '@/store/setting/hook' + +export default memo(() => { + const t = useI18n() + const isDynamicBg = useSettingValue('theme.dynamicBg') + const setIsDynamicBg = (isDynamicBg: boolean) => { + updateSetting({ 'theme.dynamicBg': isDynamicBg }) + } + + + return ( + + + + ) +}) + +const styles = createStyle({ + content: { + marginTop: 5, + // marginBottom: 15, + }, +}) diff --git a/src/screens/Home/Views/Setting/settings/Theme/Theme.tsx b/src/screens/Home/Views/Setting/settings/Theme/Theme.tsx index eef8f3e8f..79e8858b6 100644 --- a/src/screens/Home/Views/Setting/settings/Theme/Theme.tsx +++ b/src/screens/Home/Views/Setting/settings/Theme/Theme.tsx @@ -1,5 +1,5 @@ import { memo, useCallback, useEffect, useMemo, useState } from 'react' -import { View, TouchableOpacity, InteractionManager } from 'react-native' +import { View, TouchableOpacity, InteractionManager, type ImageSourcePropType } from 'react-native' import { setTheme } from '@/core/theme' import { useI18n } from '@/lang' import { useSettingValue } from '@/store/setting/hook' @@ -11,7 +11,7 @@ import Text from '@/components/common/Text' import { createStyle } from '@/utils/tools' import { scaleSizeH } from '@/utils/pixelRatio' import { Icon } from '@/components/common/Icon' -import ImageBackground, { type ImageSourceType } from '@/components/common/ImageBackground' +import ImageBackground from '@/components/common/ImageBackground' const useActive = (id: string) => { const activeThemeId = useSettingValue('theme.id') @@ -24,7 +24,7 @@ const ThemeItem = ({ id, name, color, image, setTheme, showAll }: { name: string color: string showAll: boolean - image?: ImageSourceType + image?: ImageSourcePropType setTheme: (id: string) => void }) => { const theme = useTheme() @@ -38,7 +38,7 @@ const ThemeItem = ({ id, name, color, image, setTheme, showAll }: { image ? + source={image} /> : } diff --git a/src/screens/Home/Views/Setting/settings/Theme/index.tsx b/src/screens/Home/Views/Setting/settings/Theme/index.tsx index 0e117a0da..340023528 100644 --- a/src/screens/Home/Views/Setting/settings/Theme/index.tsx +++ b/src/screens/Home/Views/Setting/settings/Theme/index.tsx @@ -4,6 +4,7 @@ import { memo } from 'react' import Theme from './Theme' import IsAutoTheme from './IsAutoTheme' import IsHideBgDark from './IsHideBgDark' +import IsDynamicBg from './IsDynamicBg' // import { useI18n } from '@/lang/i18n' export default memo(() => { @@ -11,6 +12,7 @@ export default memo(() => { <> + ) diff --git a/src/types/app_setting.d.ts b/src/types/app_setting.d.ts index e2704756c..be7e08da9 100644 --- a/src/types/app_setting.d.ts +++ b/src/types/app_setting.d.ts @@ -76,6 +76,11 @@ declare global { */ 'theme.hideBgDark': boolean + /** + * 动态背景 + */ + 'theme.dynamicBg': boolean + /** * 启动时自动播放歌曲 */ diff --git a/src/types/theme.d.ts b/src/types/theme.d.ts index 8ea33bb5a..105151e85 100644 --- a/src/types/theme.d.ts +++ b/src/types/theme.d.ts @@ -1,5 +1,4 @@ -import type { ImageSourceType } from '@/components/common/ImageBackground' - +import type { ImageSourcePropType } from 'react-native' declare global { namespace LX { @@ -280,7 +279,7 @@ declare global { 'c-list-header-border-bottom': string 'c-content-background': string 'c-border-background': string - 'bg-image'?: ImageSourceType + 'bg-image'?: ImageSourcePropType } interface Theme {