调整设置界面竖屏下的UI布局

This commit is contained in:
lyswhut 2023-03-30 17:43:22 +08:00
parent b5201495f1
commit 693baabc1a
13 changed files with 206 additions and 93 deletions

View File

@ -6,6 +6,7 @@
- 更新设置界面菜单布局 - 更新设置界面菜单布局
- 添加歌单分类、排行榜激活指示器 - 添加歌单分类、排行榜激活指示器
- 调整设置界面竖屏下的UI布局
### 修复 ### 修复

View File

@ -1,6 +1,6 @@
import { setNavActiveId } from '@/core/common' import { setNavActiveId } from '@/core/common'
import Event from './Event' import Event from './Event'
import commonState, { type InitState as CommonState } from '@/store/common/state' import commonState from '@/store/common/state'
import { type Source as SonglistSource } from '@/store/songlist/state' import { type Source as SonglistSource } from '@/store/songlist/state'
import { type SearchType } from '@/store/search/state' import { type SearchType } from '@/store/search/state'
@ -162,10 +162,6 @@ export class AppEvent extends Event {
this.emit('changeMenuVisible', visible) this.emit('changeMenuVisible', visible)
} }
homeNavPagerChanged(id: CommonState['navActiveId']) {
this.emit('homeNavPagerChanged', id)
}
/** /**
* *
* @param type * @param type

View File

@ -204,6 +204,7 @@
"setting_basic_theme": "Theme", "setting_basic_theme": "Theme",
"setting_basic_theme_auto_theme": "Follow the system light and dark mode to switch themes", "setting_basic_theme_auto_theme": "Follow the system light and dark mode to switch themes",
"setting_basic_theme_hide_bg_dark": "Hide black theme", "setting_basic_theme_hide_bg_dark": "Hide black theme",
"setting_basic_theme_more_btn_show": "Expand 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

@ -204,6 +204,7 @@
"setting_basic_theme": "主题颜色", "setting_basic_theme": "主题颜色",
"setting_basic_theme_auto_theme": "跟随系统亮、暗模式切换主题", "setting_basic_theme_auto_theme": "跟随系统亮、暗模式切换主题",
"setting_basic_theme_hide_bg_dark": "隐藏黑色主题背景", "setting_basic_theme_hide_bg_dark": "隐藏黑色主题背景",
"setting_basic_theme_more_btn_show": "更多主题",
"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

@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { View } from 'react-native' import { InteractionManager, View } from 'react-native'
import Search from '../Views/Search' import Search from '../Views/Search'
import SongList from '../Views/SongList' import SongList from '../Views/SongList'
import Mylist from '../Views/Mylist' import Mylist from '../Views/Mylist'
@ -16,7 +16,13 @@ const SearchPage = () => {
const component = useMemo(() => <Search />, []) const component = useMemo(() => <Search />, [])
useEffect(() => { useEffect(() => {
const handleNavIdUpdate = (id: CommonState['navActiveId']) => { const handleNavIdUpdate = (id: CommonState['navActiveId']) => {
if (id == 'nav_search') setVisible(true) if (id == 'nav_search') {
requestAnimationFrame(() => {
void InteractionManager.runAfterInteractions(() => {
setVisible(true)
})
})
}
} }
const handleHide = () => { const handleHide = () => {
setVisible(false) setVisible(false)
@ -39,7 +45,13 @@ const SongListPage = () => {
const component = useMemo(() => <SongList />, []) const component = useMemo(() => <SongList />, [])
useEffect(() => { useEffect(() => {
const handleNavIdUpdate = (id: CommonState['navActiveId']) => { const handleNavIdUpdate = (id: CommonState['navActiveId']) => {
if (id == 'nav_songlist') setVisible(true) if (id == 'nav_songlist') {
requestAnimationFrame(() => {
void InteractionManager.runAfterInteractions(() => {
setVisible(true)
})
})
}
} }
const handleHide = () => { const handleHide = () => {
setVisible(false) setVisible(false)
@ -63,7 +75,13 @@ const LeaderboardPage = () => {
const component = useMemo(() => <Leaderboard />, []) const component = useMemo(() => <Leaderboard />, [])
useEffect(() => { useEffect(() => {
const handleNavIdUpdate = (id: CommonState['navActiveId']) => { const handleNavIdUpdate = (id: CommonState['navActiveId']) => {
if (id == 'nav_top') setVisible(true) if (id == 'nav_top') {
requestAnimationFrame(() => {
void InteractionManager.runAfterInteractions(() => {
setVisible(true)
})
})
}
} }
const handleHide = () => { const handleHide = () => {
setVisible(false) setVisible(false)
@ -86,7 +104,13 @@ const MylistPage = () => {
const component = useMemo(() => <Mylist />, []) const component = useMemo(() => <Mylist />, [])
useEffect(() => { useEffect(() => {
const handleNavIdUpdate = (id: CommonState['navActiveId']) => { const handleNavIdUpdate = (id: CommonState['navActiveId']) => {
if (id == 'nav_love') setVisible(true) if (id == 'nav_love') {
requestAnimationFrame(() => {
void InteractionManager.runAfterInteractions(() => {
setVisible(true)
})
})
}
} }
const handleHide = () => { const handleHide = () => {
setVisible(false) setVisible(false)
@ -109,7 +133,13 @@ const SettingPage = () => {
const component = useMemo(() => <Setting />, []) const component = useMemo(() => <Setting />, [])
useEffect(() => { useEffect(() => {
const handleNavIdUpdate = (id: CommonState['navActiveId']) => { const handleNavIdUpdate = (id: CommonState['navActiveId']) => {
if (id == 'nav_setting') setVisible(true) if (id == 'nav_setting') {
requestAnimationFrame(() => {
void InteractionManager.runAfterInteractions(() => {
setVisible(true)
})
})
}
} }
global.state_event.on('navActiveIdUpdated', handleNavIdUpdate) global.state_event.on('navActiveIdUpdated', handleNavIdUpdate)
@ -162,7 +192,6 @@ const Main = () => {
if (activeIndexRef.current != viewMap[commonState.navActiveId]) { if (activeIndexRef.current != viewMap[commonState.navActiveId]) {
setNavActiveId(indexMap[activeIndexRef.current]) setNavActiveId(indexMap[activeIndexRef.current])
} }
global.app_event.homeNavPagerChanged(indexMap[activeIndexRef.current])
}, []) }, [])
const onPageScrollStateChanged = useCallback(({ nativeEvent }: PageScrollStateChangedNativeEvent) => { const onPageScrollStateChanged = useCallback(({ nativeEvent }: PageScrollStateChangedNativeEvent) => {

View File

@ -2,7 +2,6 @@ import React, { forwardRef, useImperativeHandle, useMemo, useState } from 'react
import { InteractionManager } from 'react-native' import { InteractionManager } from 'react-native'
import Basic from './settings/Basic' import Basic from './settings/Basic'
import Theme from './settings/Theme'
import Player from './settings/Player' import Player from './settings/Player'
import LyricDesktop from './settings/LyricDesktop' import LyricDesktop from './settings/LyricDesktop'
import Search from './settings/Search' import Search from './settings/Search'
@ -15,7 +14,6 @@ import About from './settings/About'
export const SETTING_SCREENS = [ export const SETTING_SCREENS = [
'basic', 'basic',
'theme',
'player', 'player',
'lyric_desktop', 'lyric_desktop',
'search', 'search',
@ -51,7 +49,6 @@ const Main = forwardRef<MainType, {}>((props, ref) => {
const component = useMemo(() => { const component = useMemo(() => {
switch (id) { switch (id) {
case 'theme': return <Theme />
case 'player': return <Player /> case 'player': return <Player />
case 'lyric_desktop': return <LyricDesktop /> case 'lyric_desktop': return <LyricDesktop />
case 'search': return <Search /> case 'search': return <Search />

View File

@ -0,0 +1,66 @@
import React, { memo } from 'react'
import { FlatList, type FlatListProps } from 'react-native'
import Basic from '../settings/Basic'
import Player from '../settings/Player'
import LyricDesktop from '../settings/LyricDesktop'
import Search from '../settings/Search'
import List from '../settings/List'
import Sync from '../settings/Sync'
import Backup from '../settings/Backup'
import Other from '../settings/Other'
import Version from '../settings/Version'
import About from '../settings/About'
import { createStyle } from '@/utils/tools'
import { SETTING_SCREENS, type SettingScreenIds } from '../Main'
type FlatListType = FlatListProps<SettingScreenIds>
const styles = createStyle({
content: {
paddingLeft: 15,
paddingRight: 15,
paddingTop: 15,
paddingBottom: 15,
flex: 0,
},
})
const ListItem = memo(({
id,
}: { id: SettingScreenIds }) => {
switch (id) {
case 'player': return <Player />
case 'lyric_desktop': return <LyricDesktop />
case 'search': return <Search />
case 'list': return <List />
case 'sync': return <Sync />
case 'backup': return <Backup />
case 'other': return <Other />
case 'version': return <Version />
case 'about': return <About />
case 'basic':
default: return <Basic />
}
}, () => true)
export default () => {
const renderItem: FlatListType['renderItem'] = ({ item }) => <ListItem id={item} />
const getkey: FlatListType['keyExtractor'] = item => item
return (
<FlatList
data={SETTING_SCREENS}
keyboardShouldPersistTaps={'always'}
renderItem={renderItem}
keyExtractor={getkey}
contentContainerStyle={styles.content}
maxToRenderPerBatch={2}
// updateCellsBatchingPeriod={80}
windowSize={2}
// removeClippedSubviews={true}
initialNumToRender={1}
/>
)
}

View File

@ -1,44 +1,29 @@
import React, { useCallback, useRef } from 'react' export { default } from './Main'
import { ScrollView, View, type DrawerLayoutAndroid } from 'react-native' // import React from 'react'
// import { getWindowSise, onDimensionChange } from '@/utils/tools' // import { View } from 'react-native'
import NavList from './NavList' // import Main from './Main'
import Main, { type SettingScreenIds, type MainType } from '../Main' // import { createStyle } from '@/utils/tools'
import { createStyle } from '@/utils/tools'
const Content = () => { // const Content = () => {
const drawer = useRef<DrawerLayoutAndroid>(null) // return (
const mainRef = useRef<MainType>(null) // <View style={styles.container}>
// <Main />
// </View>
// )
// }
// const styles = createStyle({
// container: {
// flex: 1,
// flexDirection: 'column',
// },
// // main: {
// // paddingLeft: 15,
// // paddingRight: 15,
// // paddingTop: 15,
// // paddingBottom: 15,
// // },
// })
const handleChangeId = useCallback((id: SettingScreenIds) => { // export default Content
drawer.current?.closeDrawer()
mainRef.current?.setActiveId(id)
}, [])
// console.log('render drawer content')
return (
<View style={styles.container}>
<NavList onChangeId={handleChangeId} />
<ScrollView contentContainerStyle={styles.main} keyboardShouldPersistTaps={'always'}>
<Main ref={mainRef} />
</ScrollView>
</View>
)
}
const styles = createStyle({
container: {
flex: 1,
flexDirection: 'column',
},
main: {
paddingLeft: 15,
paddingRight: 15,
paddingTop: 15,
paddingBottom: 15,
},
})
export default Content

View File

@ -1,5 +1,6 @@
import React, { memo } from 'react' import React, { memo } from 'react'
import Theme from '../Theme'
import Section from '../../components/Section' import Section from '../../components/Section'
import Source from './Source' import Source from './Source'
import SourceName from './SourceName' import SourceName from './SourceName'
@ -23,12 +24,13 @@ export default memo(() => {
<IsShowBackBtn /> <IsShowBackBtn />
<IsShowExitBtn /> <IsShowExitBtn />
<IsAutoHidePlayBar /> <IsAutoHidePlayBar />
<Source /> <Theme />
<SourceName />
<DrawerLayoutPosition /> <DrawerLayoutPosition />
<Language /> <Language />
<FontSize /> <FontSize />
<ShareType /> <ShareType />
<Source />
<SourceName />
</Section> </Section>
) )
}) })

View File

@ -32,6 +32,6 @@ export default memo(() => {
const styles = createStyle({ const styles = createStyle({
content: { content: {
marginTop: 5, marginTop: 5,
// marginBottom: 5, marginBottom: 15,
}, },
}) })

View File

@ -10,6 +10,7 @@ import { BG_IMAGES, getAllThemes, type LocalTheme } from '@/theme/themes'
import Text from '@/components/common/Text' import Text from '@/components/common/Text'
import { createStyle } from '@/utils/tools' import { createStyle } from '@/utils/tools'
import { scaleSizeH } from '@/utils/pixelRatio' import { scaleSizeH } from '@/utils/pixelRatio'
import { Icon } from '@/components/common/Icon'
const useActive = (id: string) => { const useActive = (id: string) => {
const activeThemeId = useSettingValue('theme.id') const activeThemeId = useSettingValue('theme.id')
@ -17,10 +18,11 @@ const useActive = (id: string) => {
return isActive return isActive
} }
const ThemeItem = ({ id, name, color, image, setTheme }: { const ThemeItem = ({ id, name, color, image, setTheme, showAll }: {
id: string id: string
name: string name: string
color: string color: string
showAll: boolean
image?: ImageSourcePropType image?: ImageSourcePropType
setTheme: (id: string) => void setTheme: (id: string) => void
}) => { }) => {
@ -28,6 +30,7 @@ const ThemeItem = ({ id, name, color, image, setTheme }: {
const isActive = useActive(id) const isActive = useActive(id)
return ( return (
showAll || isActive ? (
<TouchableOpacity style={{ ...styles.item, width: scaleSizeH(ITEM_HEIGHT) }} activeOpacity={0.5} onPress={() => { setTheme(id) }}> <TouchableOpacity style={{ ...styles.item, width: scaleSizeH(ITEM_HEIGHT) }} activeOpacity={0.5} onPress={() => { setTheme(id) }}>
<View style={{ ...styles.colorContent, width: scaleSizeH(COLOR_ITEM_HEIGHT), borderColor: isActive ? color : 'transparent' }}> <View style={{ ...styles.colorContent, width: scaleSizeH(COLOR_ITEM_HEIGHT), borderColor: isActive ? color : 'transparent' }}>
{ {
@ -39,6 +42,26 @@ const ThemeItem = ({ id, name, color, image, setTheme }: {
</View> </View>
<Text style={styles.name} size={12} color={isActive ? color : theme['c-font']} numberOfLines={1}>{name}</Text> <Text style={styles.name} size={12} color={isActive ? color : theme['c-font']} numberOfLines={1}>{name}</Text>
</TouchableOpacity> </TouchableOpacity>
) : null
)
}
const MoreBtn = ({ showAll, setShowAll }: {
showAll: boolean
setShowAll: (showAll: boolean) => void
}) => {
const theme = useTheme()
const t = useI18n()
return (
showAll ? null
: (
<TouchableOpacity style={styles.moreBtn} activeOpacity={0.5} onPress={() => { setShowAll(!showAll) }}>
<Text size={14} color={theme['c-primary-font']} numberOfLines={1}>{t('setting_basic_theme_more_btn_show')}</Text>
<Icon name="chevron-right" size={12} color={theme['c-primary-font']} />
</TouchableOpacity>
)
) )
} }
@ -49,6 +72,7 @@ interface ThemeInfo {
} }
const initInfo: ThemeInfo = { themes: [], userThemes: [], dataPath: '' } const initInfo: ThemeInfo = { themes: [], userThemes: [], dataPath: '' }
export default memo(() => { export default memo(() => {
const [showAll, setShowAll] = useState(false)
const t = useI18n() const t = useI18n()
const [themeInfo, setThemeInfo] = useState(initInfo) const [themeInfo, setThemeInfo] = useState(initInfo)
const setThemeId = useCallback((id: string) => { const setThemeId = useCallback((id: string) => {
@ -70,6 +94,7 @@ export default memo(() => {
key={id} key={id}
color={config.themeColors['c-theme']} color={config.themeColors['c-theme']}
image={config.extInfo['bg-image'] ? BG_IMAGES[config.extInfo['bg-image']] : undefined} image={config.extInfo['bg-image'] ? BG_IMAGES[config.extInfo['bg-image']] : undefined}
showAll={showAll}
id={id} id={id}
name={t(`theme_${id}`)} name={t(`theme_${id}`)}
setTheme={setThemeId} /> setTheme={setThemeId} />
@ -81,28 +106,31 @@ export default memo(() => {
key={id} key={id}
color={config.themeColors['c-theme']} color={config.themeColors['c-theme']}
// image={undefined} // image={undefined}
showAll={showAll}
id={id} id={id}
name={name} name={name}
setTheme={setThemeId} /> setTheme={setThemeId} />
}) })
} }
<MoreBtn showAll={showAll} setShowAll={setShowAll} />
</View> </View>
</SubTitle> </SubTitle>
) )
}) })
const ITEM_HEIGHT = 56 const ITEM_HEIGHT = 62
const COLOR_ITEM_HEIGHT = 34 const COLOR_ITEM_HEIGHT = 36
const IMAGE_HEIGHT = 27 const IMAGE_HEIGHT = 29
const styles = createStyle({ const styles = createStyle({
list: { list: {
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'wrap', flexWrap: 'wrap',
gap: 10,
}, },
item: { item: {
marginRight: 15, // marginRight: 15,
alignItems: 'center', alignItems: 'center',
marginTop: 5, // marginTop: 5,
// backgroundColor: 'rgba(0,0,0,0.2)', // backgroundColor: 'rgba(0,0,0,0.2)',
}, },
colorContent: { colorContent: {
@ -111,6 +139,7 @@ const styles = createStyle({
borderWidth: 1.6, borderWidth: 1.6,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
// backgroundColor: 'rgba(0,0,0,0.2)',
}, },
imageContent: { imageContent: {
height: IMAGE_HEIGHT, height: IMAGE_HEIGHT,
@ -120,4 +149,11 @@ const styles = createStyle({
name: { name: {
marginTop: 2, marginTop: 2,
}, },
moreBtn: {
marginLeft: 10,
flexDirection: 'row',
alignItems: 'center',
// justifyContent: 'center',
gap: 8,
},
}) })

View File

@ -1,19 +1,17 @@
import React, { memo } from 'react' import React, { memo } from 'react'
import Section from '../../components/Section' // import Section from '../../components/Section'
import Theme from './Theme' import Theme from './Theme'
import IsAutoTheme from './IsAutoTheme' import IsAutoTheme from './IsAutoTheme'
import IsHideBgDark from './IsHideBgDark' import IsHideBgDark from './IsHideBgDark'
import { useI18n } from '@/lang/i18n' // import { useI18n } from '@/lang/i18n'
export default memo(() => { export default memo(() => {
const t = useI18n()
return ( return (
<Section title={t('setting_theme')}> <>
<Theme /> <Theme />
<IsAutoTheme /> <IsAutoTheme />
<IsHideBgDark /> <IsHideBgDark />
</Section> </>
) )
}) })

View File

@ -395,6 +395,7 @@ export const trasformeStyle = <T extends Style>(styles: T): T => {
case 'paddingLeft': case 'paddingLeft':
case 'paddingRight': case 'paddingRight':
case 'paddingHorizontal': case 'paddingHorizontal':
case 'gap':
newStyle[p] = scaleSizeW(v) newStyle[p] = scaleSizeW(v)
break break
case 'padding': case 'padding':