新增设置-基本设置-主题颜色-跟随系统亮、暗模式切换主题设置

This commit is contained in:
lyswhut 2022-04-09 23:29:45 +08:00
parent 2fafb5440c
commit 6989d09c5b
11 changed files with 99 additions and 13 deletions

View File

@ -6,4 +6,11 @@
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item> <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
<item name="android:forceDarkAllowed">false</item> <item name="android:forceDarkAllowed">false</item>
</style> </style>
<style name="SplashScreenTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
<!-- <item name="android:windowBackground">@drawable/launch_screen</item> -->
<item name="android:windowFullscreen">true</item>
<item name="android:forceDarkAllowed">true</item>
</style>
</resources> </resources>

View File

@ -19,7 +19,7 @@ import { init as initMusicTools } from '@/utils/music'
import { init as initLyric, toggleTranslation } from '@/utils/lyric' import { init as initLyric, toggleTranslation } from '@/utils/lyric'
import { showLyric, onPositionChange } from '@/utils/lyricDesktop' import { showLyric, onPositionChange } from '@/utils/lyricDesktop'
import { init as initI18n, supportedLngs } from '@/plugins/i18n' import { init as initI18n, supportedLngs } from '@/plugins/i18n'
import { deviceLanguage, getPlayInfo, toast } from '@/utils/tools' import { deviceLanguage, getPlayInfo, toast, onAppearanceChange, getIsSupportedAutoTheme } from '@/utils/tools'
import { LIST_ID_PLAY_TEMP } from '@/config/constant' import { LIST_ID_PLAY_TEMP } from '@/config/constant'
import { connect, SYNC_CODE } from '@/plugins/sync' import { connect, SYNC_CODE } from '@/plugins/sync'
@ -42,6 +42,13 @@ const init = () => {
registerPlaybackService(), registerPlaybackService(),
]).then(() => { ]).then(() => {
let setting = store.getState().common.setting let setting = store.getState().common.setting
if (getIsSupportedAutoTheme()) {
onAppearanceChange(color => {
store.dispatch(commonAction.setSystemColor(color))
})
}
toggleTranslation(setting.player.isShowLyricTranslation) toggleTranslation(setting.player.isShowLyricTranslation)
if (setting.sync.enable) { if (setting.sync.enable) {
connect().catch(err => { connect().catch(err => {

View File

@ -4,6 +4,7 @@
- 新增设置-基本设置-分享设置,它用于控制歌曲菜单的分享行为,默认使用系统分享 - 新增设置-基本设置-分享设置,它用于控制歌曲菜单的分享行为,默认使用系统分享
- 新增是否在通知栏显示歌曲图片设置,默认开启(原来的行为) - 新增是否在通知栏显示歌曲图片设置,默认开启(原来的行为)
- 新增黑色皮肤“黑灯瞎火” - 新增黑色皮肤“黑灯瞎火”
- 新增设置-基本设置-主题颜色-跟随系统亮、暗模式切换主题设置此设置需要android 10或ios 13及以上的版本才支持
### 优化 ### 优化

View File

@ -4,7 +4,7 @@
import { MUSIC_TOGGLE_MODE } from './constant' import { MUSIC_TOGGLE_MODE } from './constant'
const defaultSetting = { const defaultSetting = {
version: '1.18', version: '1.19',
player: { player: {
togglePlayMethod: MUSIC_TOGGLE_MODE.listLoop, togglePlayMethod: MUSIC_TOGGLE_MODE.listLoop,
highQuality: false, highQuality: false,
@ -98,6 +98,7 @@ const defaultSetting = {
// }, // },
// }, // },
themeId: 'green', themeId: 'green',
isAutoTheme: true,
langId: null, langId: null,
sourceId: 'kw', sourceId: 'kw',
apiSource: 'temp', apiSource: 'temp',

View File

@ -133,6 +133,7 @@
"setting_basic_sourcename_real": "Original", "setting_basic_sourcename_real": "Original",
"setting_basic_sourcename_title": "Select the name of music source", "setting_basic_sourcename_title": "Select the name of music source",
"setting_basic_theme": "Theme", "setting_basic_theme": "Theme",
"setting_basic_theme_auto_theme": "Follow the system light and dark mode to switch themes",
"setting_list": "List settings", "setting_list": "List settings",
"setting_list_add_music_location_type": "Position when the song was added to the list", "setting_list_add_music_location_type": "Position when the song was added to the list",
"setting_list_add_music_location_type_bottom": "Bottom", "setting_list_add_music_location_type_bottom": "Bottom",

View File

@ -134,6 +134,7 @@
"setting_basic_sourcename_real": "原名", "setting_basic_sourcename_real": "原名",
"setting_basic_sourcename_title": "选择音源名字类型", "setting_basic_sourcename_title": "选择音源名字类型",
"setting_basic_theme": "主题颜色", "setting_basic_theme": "主题颜色",
"setting_basic_theme_auto_theme": "跟随系统亮、暗模式切换主题",
"setting_list": "列表设置", "setting_list": "列表设置",
"setting_list_add_music_location_type": "添加歌曲到列表时的位置", "setting_list_add_music_location_type": "添加歌曲到列表时的位置",
"setting_list_add_music_location_type_bottom": "底部", "setting_list_add_music_location_type_bottom": "底部",

View File

@ -4,7 +4,10 @@ import { StyleSheet, View, Text, ImageBackground, TouchableOpacity, InteractionM
import { useGetter, useDispatch } from '@/store' import { useGetter, useDispatch } from '@/store'
import SubTitle from '../components/SubTitle' import SubTitle from '../components/SubTitle'
import CheckBoxItem from '../components/CheckBoxItem'
import { useTranslation } from '@/plugins/i18n' import { useTranslation } from '@/plugins/i18n'
import { getIsSupportedAutoTheme } from '@/utils/tools'
const isSupportedAutoTheme = getIsSupportedAutoTheme()
const useActive = id => { const useActive = id => {
const activeThemeId = useGetter('common', 'activeThemeId') const activeThemeId = useGetter('common', 'activeThemeId')
@ -41,6 +44,9 @@ export default memo(() => {
}) })
}, [setTheme]) }, [setTheme])
const isAutoTheme = useGetter('common', 'isAutoTheme')
const setIsAutoTheme = useDispatch('common', 'setIsAutoTheme')
return ( return (
<SubTitle title={t('setting_basic_theme')}> <SubTitle title={t('setting_basic_theme')}>
<View style={styles.list}> <View style={styles.list}>
@ -48,6 +54,17 @@ export default memo(() => {
themes.map(({ id, color, image }) => <ThemeItem key={id} color={color} image={image} id={id} setTheme={setThemeId} />) themes.map(({ id, color, image }) => <ThemeItem key={id} color={color} image={image} id={id} setTheme={setThemeId} />)
} }
</View> </View>
{
isSupportedAutoTheme
? (
<View style={{ marginTop: 25, marginLeft: -25 }}>
<CheckBoxItem check={isAutoTheme} onChange={setIsAutoTheme} label={t('setting_basic_theme_auto_theme')} />
</View>
)
: null
}
</SubTitle> </SubTitle>
) )
}) })

View File

@ -1,4 +1,4 @@
import { getData, setData, removeData, getAllKeys, getDataMultiple, setDataMultiple } from '@/plugins/storage' import { getData, setData } from '@/plugins/storage'
import { storageDataPrefix } from '@/config' import { storageDataPrefix } from '@/config'
import { action as playerAction, getter as playerGetter } from '@/store/modules/player' import { action as playerAction, getter as playerGetter } from '@/store/modules/player'
import { mergeSetting } from '@/config/setting' import { mergeSetting } from '@/config/setting'
@ -21,6 +21,8 @@ export const TYPES = {
setPrevSelectListId: null, setPrevSelectListId: null,
setApiSource: null, setApiSource: null,
setTheme: null, setTheme: null,
setIsAutoTheme: null,
setSystemColor: null,
setSearchSource: null, setSearchSource: null,
setAgreePact: null, setAgreePact: null,
setSongList: null, setSongList: null,
@ -193,6 +195,20 @@ export const setTheme = id => async(dispatch, getState) => {
await setData(settingKey, common.setting) await setData(settingKey, common.setting)
} }
export const setIsAutoTheme = enabled => async(dispatch, getState) => {
dispatch({
type: TYPES.setIsAutoTheme,
payload: enabled,
})
const { common } = getState()
await setData(settingKey, common.setting)
}
export const setSystemColor = color => ({
type: TYPES.setSystemColor,
payload: color,
})
export const setLang = id => async(dispatch, getState) => { export const setLang = id => async(dispatch, getState) => {
dispatch({ dispatch({
type: TYPES.setLang, type: TYPES.setLang,

View File

@ -23,17 +23,19 @@ export const isPlayHighQuality = state => state.common.setting.player.highQualit
export const isHandleAudioFocus = state => state.common.setting.player.isHandleAudioFocus export const isHandleAudioFocus = state => state.common.setting.player.isHandleAudioFocus
export const playerCacheSize = state => state.common.setting.player.cacheSize export const playerCacheSize = state => state.common.setting.player.cacheSize
export const systemColor = state => state.common.systemColor
export const isAutoTheme = state => state.common.setting.isAutoTheme
export const themeList = state => state.common.themes export const themeList = state => state.common.themes
export const activeThemeId = state => state.common.setting.themeId export const activeThemeId = state => state.common.setting.themeId
export const theme = createSelector( export const activeTheme = createSelector(
[themeList, activeThemeId], [themeList, activeThemeId, isAutoTheme, systemColor],
(themeList, activeThemeId) => (themeList.find(theme => theme.id === activeThemeId) || themeList[0]).colors) (themeList, activeThemeId, isAutoTheme, systemColor) => {
export const isDarkTheme = createSelector( const themeId = isAutoTheme && systemColor == 'dark' ? 'black' : activeThemeId
[themeList, activeThemeId], return themeList.find(theme => theme.id === themeId) || themeList[0]
(themeList, activeThemeId) => (themeList.find(theme => theme.id === activeThemeId) || themeList[0]).isDark) })
export const statusBarStyle = createSelector( export const theme = createSelector(activeTheme, activeTheme => activeTheme.colors)
isDarkTheme, export const isDarkTheme = createSelector(activeTheme, activeTheme => activeTheme.isDark)
isDarkTheme => isDarkTheme ? 'light-content' : 'dark-content') export const statusBarStyle = createSelector(isDarkTheme, isDarkTheme => isDarkTheme ? 'light-content' : 'dark-content')
export const versionInfo = state => state.common.versionInfo export const versionInfo = state => state.common.versionInfo

View File

@ -28,6 +28,7 @@ const initialState = {
}, },
qualityList: music.supportQuality[setting.setting.apiSource], qualityList: music.supportQuality[setting.setting.apiSource],
themes: Themes, themes: Themes,
systemColor: null,
versionInfo: { versionInfo: {
status: VERSION_STATUS.checking, status: VERSION_STATUS.checking,
downloadProgress: { downloadProgress: {
@ -212,6 +213,21 @@ const mutations = {
}, },
} }
}, },
[TYPES.setIsAutoTheme](state, enabled) {
return {
...state,
setting: {
...state.setting,
isAutoTheme: enabled,
},
}
},
[TYPES.setSystemColor](state, color) {
return {
...state,
systemColor: color,
}
},
[TYPES.setLang](state, id) { [TYPES.setLang](state, id) {
return { return {
...state, ...state,

View File

@ -1,4 +1,4 @@
import { Platform, NativeModules, ToastAndroid, BackHandler, Linking, Dimensions, Alert } from 'react-native' import { Platform, NativeModules, ToastAndroid, BackHandler, Linking, Dimensions, Alert, Appearance } from 'react-native'
// import ExtraDimensions from 'react-native-extra-dimensions-android' // import ExtraDimensions from 'react-native-extra-dimensions-android'
import Clipboard from '@react-native-clipboard/clipboard' import Clipboard from '@react-native-clipboard/clipboard'
import { getData, setData, getAllKeys, removeData, removeDataMultiple, setDataMultiple, getDataMultiple } from '@/plugins/storage' import { getData, setData, getAllKeys, removeData, removeDataMultiple, setDataMultiple, getDataMultiple } from '@/plugins/storage'
@ -29,6 +29,9 @@ let deviceLanguage = Platform.OS === 'ios'
: NativeModules.I18nManager.localeIdentifier : NativeModules.I18nManager.localeIdentifier
deviceLanguage = typeof deviceLanguage === 'string' ? deviceLanguage.substring(0, 5).toLocaleLowerCase() : '' deviceLanguage = typeof deviceLanguage === 'string' ? deviceLanguage.substring(0, 5).toLocaleLowerCase() : ''
export const isAndroid = Platform.OS === 'android'
export const osVer = Platform.constants.Release
const handleSaveListScrollPosition = throttle(data => { const handleSaveListScrollPosition = throttle(data => {
setData(listPositionPrefix, data) setData(listPositionPrefix, data)
}, 1000) }, 1000)
@ -374,6 +377,20 @@ export const shareMusic = (shareType, downloadFileName, musicInfo) => {
} }
} }
export const onAppearanceChange = callback => {
callback(Appearance.getColorScheme())
return Appearance.addChangeListener(({ colorScheme }) => {
callback(colorScheme)
})
}
export const getIsSupportedAutoTheme = () => {
const osVerNum = parseInt(osVer)
return isAndroid
? osVerNum >= 10
: osVerNum >= 13
}
export { export {
deviceLanguage, deviceLanguage,
} }