修改列表布局

This commit is contained in:
lyswhut 2023-08-19 10:24:37 +08:00
parent a8b169d4d9
commit 2b83d2126b
17 changed files with 203 additions and 30 deletions

View File

@ -6,12 +6,19 @@
### 不兼容性变更 ### 不兼容性变更
该版本修改了同步协议逻辑至少需要PC端v2.4.0或移动端v1.0.7版本才能连接使用。 该版本修改了同步协议逻辑同步功能至少需要PC端v2.4.0或移动端v1.1.0或同步服务v2.0.0版本才能连接使用
### 新增
- 新增列表设置-是否显示歌曲专辑名,默认关闭
- 新增列表设置-是否显示歌曲时长,默认开启
### 优化 ### 优化
- 优化歌单列表歌单封面大小计算方式 - 优化歌单列表歌单封面大小计算方式
- 调整竖屏下的排行榜布局 - 调整竖屏下的排行榜布局
- 调整歌曲列表信息布局
- 调整横屏下的歌曲列表为两列
- 调整桌面歌词主题配色,增强歌词字体阴影(#276 - 调整桌面歌词主题配色,增强歌词字体阴影(#276
- 优化数据传输逻辑,列表同步指令使用队列机制,保证列表同步操作的顺序 - 优化数据传输逻辑,列表同步指令使用队列机制,保证列表同步操作的顺序

View File

@ -3,7 +3,7 @@ import { FlatList, type FlatListProps, RefreshControl, View } from 'react-native
// import { useMusicList } from '@/store/list/hook' // import { useMusicList } from '@/store/list/hook'
import ListItem, { ITEM_HEIGHT } from './ListItem' import ListItem, { ITEM_HEIGHT } from './ListItem'
import { createStyle } from '@/utils/tools' import { createStyle, getRowInfo, type RowInfoType } from '@/utils/tools'
import type { Position } from './ListMenu' import type { Position } from './ListMenu'
import type { SelectMode } from './MultipleModeBar' import type { SelectMode } from './MultipleModeBar'
import { useTheme } from '@/store/theme/hook' import { useTheme } from '@/store/theme/hook'
@ -12,9 +12,14 @@ import { MULTI_SELECT_BAR_HEIGHT } from './MultipleModeBar'
import { useI18n } from '@/lang' import { useI18n } from '@/lang'
import Text from '@/components/common/Text' import Text from '@/components/common/Text'
import { handlePlay } from './listAction' import { handlePlay } from './listAction'
import { useSettingValue } from '@/store/setting/hook'
type FlatListType = FlatListProps<LX.Music.MusicInfoOnline> type FlatListType = FlatListProps<LX.Music.MusicInfoOnline>
export type {
RowInfoType,
}
export interface ListProps { export interface ListProps {
onShowMenu: (musicInfo: LX.Music.MusicInfoOnline, index: number, position: Position) => void onShowMenu: (musicInfo: LX.Music.MusicInfoOnline, index: number, position: Position) => void
onMuiltSelectMode: () => void onMuiltSelectMode: () => void
@ -25,6 +30,7 @@ export interface ListProps {
progressViewOffset?: number progressViewOffset?: number
ListHeaderComponent?: FlatListType['ListEmptyComponent'] ListHeaderComponent?: FlatListType['ListEmptyComponent']
checkHomePagerIdle: boolean checkHomePagerIdle: boolean
rowType?: RowInfoType
} }
export interface ListType { export interface ListType {
setList: (list: LX.Music.MusicInfoOnline[], isAppend: boolean, showSource: boolean) => void setList: (list: LX.Music.MusicInfoOnline[], isAppend: boolean, showSource: boolean) => void
@ -48,6 +54,7 @@ const List = forwardRef<ListType, ListProps>(({
progressViewOffset, progressViewOffset,
ListHeaderComponent, ListHeaderComponent,
checkHomePagerIdle, checkHomePagerIdle,
rowType,
}, ref) => { }, ref) => {
// const t = useI18n() // const t = useI18n()
const theme = useTheme() const theme = useTheme()
@ -61,6 +68,9 @@ const List = forwardRef<ListType, ListProps>(({
const selectedListRef = useRef<LX.Music.MusicInfoOnline[]>([]) const selectedListRef = useRef<LX.Music.MusicInfoOnline[]>([])
const [visibleMultiSelect, setVisibleMultiSelect] = useState(false) const [visibleMultiSelect, setVisibleMultiSelect] = useState(false)
const [status, setStatus] = useState<Status>('idle') const [status, setStatus] = useState<Status>('idle')
const rowInfo = useRef(getRowInfo(rowType))
const isShowAlbumName = useSettingValue('list.isShowAlbumName')
const isShowInterval = useSettingValue('list.isShowInterval')
// const currentListIdRef = useRef('') // const currentListIdRef = useRef('')
// console.log('render music list') // console.log('render music list')
@ -179,6 +189,9 @@ const List = forwardRef<ListType, ListProps>(({
onLongPress={handleLongPress} onLongPress={handleLongPress}
onShowMenu={onShowMenu} onShowMenu={onShowMenu}
selectedList={selectedList} selectedList={selectedList}
rowInfo={rowInfo.current}
isShowAlbumName={isShowAlbumName}
isShowInterval={isShowInterval}
/> />
) )
const getkey: FlatListType['keyExtractor'] = item => item.id const getkey: FlatListType['keyExtractor'] = item => item.id
@ -221,6 +234,8 @@ const List = forwardRef<ListType, ListProps>(({
ref={flatListRef} ref={flatListRef}
style={styles.list} style={styles.list}
data={currentList} data={currentList}
numColumns={rowInfo.current.rowNum}
horizontal={false}
maxToRenderPerBatch={4} maxToRenderPerBatch={4}
// updateCellsBatchingPeriod={80} // updateCellsBatchingPeriod={80}
windowSize={8} windowSize={8}

View File

@ -1,5 +1,5 @@
import React, { memo, useRef } from 'react' import React, { memo, useRef } from 'react'
import { StyleSheet, View, TouchableOpacity } from 'react-native' import { View, TouchableOpacity } from 'react-native'
// import Button from '@/components/common/Button' // import Button from '@/components/common/Button'
import Text from '@/components/common/Text' import Text from '@/components/common/Text'
import Badge, { type BadgeType } from '@/components/common/Badge' import Badge, { type BadgeType } from '@/components/common/Badge'
@ -8,6 +8,7 @@ import { useI18n } from '@/lang'
import { useTheme } from '@/store/theme/hook' import { useTheme } from '@/store/theme/hook'
import { scaleSizeH } from '@/utils/pixelRatio' import { scaleSizeH } from '@/utils/pixelRatio'
import { LIST_ITEM_HEIGHT } from '@/config/constant' import { LIST_ITEM_HEIGHT } from '@/config/constant'
import { createStyle, type RowInfo } from '@/utils/tools'
export const ITEM_HEIGHT = scaleSizeH(LIST_ITEM_HEIGHT) export const ITEM_HEIGHT = scaleSizeH(LIST_ITEM_HEIGHT)
@ -28,7 +29,7 @@ const useQualityTag = (musicInfo: LX.Music.MusicInfoOnline) => {
return info return info
} }
export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu, selectedList }: { export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu, selectedList, rowInfo, isShowAlbumName, isShowInterval }: {
item: LX.Music.MusicInfoOnline item: LX.Music.MusicInfoOnline
index: number index: number
showSource?: boolean showSource?: boolean
@ -36,6 +37,9 @@ export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu
onLongPress: (item: LX.Music.MusicInfoOnline, index: number) => void onLongPress: (item: LX.Music.MusicInfoOnline, index: number) => void
onShowMenu: (item: LX.Music.MusicInfoOnline, index: number, position: { x: number, y: number, w: number, h: number }) => void onShowMenu: (item: LX.Music.MusicInfoOnline, index: number, position: { x: number, y: number, w: number, h: number }) => void
selectedList: LX.Music.MusicInfoOnline[] selectedList: LX.Music.MusicInfoOnline[]
rowInfo: RowInfo
isShowAlbumName: boolean
isShowInterval: boolean
}) => { }) => {
const theme = useTheme() const theme = useTheme()
@ -52,18 +56,25 @@ export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu
} }
const tagInfo = useQualityTag(item) const tagInfo = useQualityTag(item)
const singer = `${item.singer}${isShowAlbumName && item.meta.albumName ? ` · ${item.meta.albumName}` : ''}`
return ( return (
<View style={{ ...styles.listItem, height: ITEM_HEIGHT, backgroundColor: isSelected ? theme['c-primary-background-hover'] : 'rgba(0,0,0,0)' }}> <View style={{ ...styles.listItem, width: rowInfo.rowWidth, height: ITEM_HEIGHT, backgroundColor: isSelected ? theme['c-primary-background-hover'] : 'rgba(0,0,0,0)' }}>
<TouchableOpacity style={styles.listItemLeft} onPress={() => { onPress(item, index) }} onLongPress={() => { onLongPress(item, index) }}> <TouchableOpacity style={styles.listItemLeft} onPress={() => { onPress(item, index) }} onLongPress={() => { onLongPress(item, index) }}>
<Text style={styles.sn} size={13} color={theme['c-300']}>{index + 1}</Text> <Text style={styles.sn} size={13} color={theme['c-300']}>{index + 1}</Text>
<View style={styles.itemInfo}> <View style={styles.itemInfo}>
<Text numberOfLines={1}>{item.name}</Text> <Text numberOfLines={1}>{item.name}</Text>
<View style={styles.listItemSingle}> <View style={styles.listItemSingle}>
<Text style={styles.listItemSingleText} size={13} color={theme['c-500']} numberOfLines={1}>{item.singer}</Text>
{ tagInfo.type ? <Badge type={tagInfo.type}>{tagInfo.text}</Badge> : null } { tagInfo.type ? <Badge type={tagInfo.type}>{tagInfo.text}</Badge> : null }
{ showSource ? <Badge type="tertiary">{item.source}</Badge> : null } { showSource ? <Badge type="tertiary">{item.source}</Badge> : null }
<Text style={styles.listItemSingleText} size={11} color={theme['c-500']} numberOfLines={1}>{singer}</Text>
</View> </View>
</View> </View>
{
isShowInterval ? (
<Text size={12} color={theme['c-300']} numberOfLines={1}>{item.interval}</Text>
) : null
}
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity onPress={handleShowMenu} ref={moreButtonRef} style={styles.moreButton}> <TouchableOpacity onPress={handleShowMenu} ref={moreButtonRef} style={styles.moreButton}>
<Icon name="dots-vertical" style={{ color: theme['c-350'] }} size={12} /> <Icon name="dots-vertical" style={{ color: theme['c-350'] }} size={12} />
@ -77,9 +88,9 @@ export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu
) )
}) })
const styles = StyleSheet.create({ const styles = createStyle({
listItem: { listItem: {
width: '100%', // width: '100%',
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'nowrap', flexWrap: 'nowrap',
// paddingLeft: 10, // paddingLeft: 10,
@ -103,8 +114,9 @@ const styles = StyleSheet.create({
paddingRight: 3, paddingRight: 3,
}, },
itemInfo: { itemInfo: {
flexGrow: 0, flexGrow: 1,
flexShrink: 1, flexShrink: 1,
paddingRight: 2,
// paddingTop: 10, // paddingTop: 10,
// paddingBottom: 10, // paddingBottom: 10,
}, },
@ -117,14 +129,20 @@ const styles = StyleSheet.create({
listItemSingle: { listItemSingle: {
paddingTop: 2, paddingTop: 2,
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center',
// alignItems: 'flex-end', // alignItems: 'flex-end',
// backgroundColor: 'rgba(0,0,0,0.2)', // backgroundColor: 'rgba(0,0,0,0.2)',
}, },
listItemTimeLabel: {
marginRight: 5,
fontWeight: '400',
},
listItemSingleText: { listItemSingleText: {
// fontSize: 13, // fontSize: 13,
// paddingTop: 2, // paddingTop: 2,
flexGrow: 0, flexGrow: 0,
flexShrink: 1, flexShrink: 1,
fontWeight: '300',
}, },
listItemBadge: { listItemBadge: {
// fontSize: 10, // fontSize: 10,

View File

@ -1,7 +1,7 @@
import React, { useRef, forwardRef, useImperativeHandle } from 'react' import React, { useRef, forwardRef, useImperativeHandle } from 'react'
import { View } from 'react-native' import { View } from 'react-native'
// import LoadingMask, { LoadingMaskType } from '@/components/common/LoadingMask' // import LoadingMask, { LoadingMaskType } from '@/components/common/LoadingMask'
import List, { type ListProps, type ListType, type Status } from './List' import List, { type ListProps, type ListType, type Status, type RowInfoType } from './List'
import ListMenu, { type ListMenuType, type Position, type SelectInfo } from './ListMenu' import ListMenu, { type ListMenuType, type Position, type SelectInfo } from './ListMenu'
import ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal' import ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal'
import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal' import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal'
@ -16,6 +16,7 @@ export interface OnlineListProps {
progressViewOffset?: ListProps['progressViewOffset'] progressViewOffset?: ListProps['progressViewOffset']
ListHeaderComponent?: ListProps['ListHeaderComponent'] ListHeaderComponent?: ListProps['ListHeaderComponent']
checkHomePagerIdle?: boolean checkHomePagerIdle?: boolean
rowType?: RowInfoType
} }
export interface OnlineListType { export interface OnlineListType {
setList: (list: LX.Music.MusicInfoOnline[], isAppend?: boolean, showSource?: boolean) => void setList: (list: LX.Music.MusicInfoOnline[], isAppend?: boolean, showSource?: boolean) => void
@ -29,6 +30,7 @@ export default forwardRef<OnlineListType, OnlineListProps>(({
progressViewOffset, progressViewOffset,
ListHeaderComponent, ListHeaderComponent,
checkHomePagerIdle = false, checkHomePagerIdle = false,
rowType,
}, ref) => { }, ref) => {
const listRef = useRef<ListType>(null) const listRef = useRef<ListType>(null)
const multipleModeBarRef = useRef<MultipleModeBarType>(null) const multipleModeBarRef = useRef<MultipleModeBarType>(null)
@ -90,6 +92,7 @@ export default forwardRef<OnlineListType, OnlineListProps>(({
progressViewOffset={progressViewOffset} progressViewOffset={progressViewOffset}
ListHeaderComponent={ListHeaderComponent} ListHeaderComponent={ListHeaderComponent}
checkHomePagerIdle={checkHomePagerIdle} checkHomePagerIdle={checkHomePagerIdle}
rowType={rowType}
/> />
<MultipleModeBar <MultipleModeBar
ref={multipleModeBarRef} ref={multipleModeBarRef}

View File

@ -12,7 +12,8 @@ const styles = createStyle({
// borderRadius: 2, // borderRadius: 2,
// lineHeight: 12, // lineHeight: 12,
// marginTop: 2, // marginTop: 2,
marginLeft: 5, marginRight: 5,
fontWeight: '400',
// marginRight: 5, // marginRight: 5,
// marginBottom: 2, // marginBottom: 2,
// alignSelf: 'flex-start', // alignSelf: 'flex-start',

View File

@ -53,6 +53,8 @@ const defaultSetting: LX.AppSetting = {
'list.isClickPlayList': false, 'list.isClickPlayList': false,
'list.isShowSource': true, 'list.isShowSource': true,
'list.isShowAlbumName': false,
'list.isShowInterval': true,
'list.isSaveScrollLocation': true, 'list.isSaveScrollLocation': true,
'list.addMusicLocationType': 'top', 'list.addMusicLocationType': 'top',

View File

@ -212,6 +212,8 @@
"setting_list_add_music_location_type_bottom": "Bottom", "setting_list_add_music_location_type_bottom": "Bottom",
"setting_list_add_music_location_type_top": "Top", "setting_list_add_music_location_type_top": "Top",
"setting_list_click_action": "When you click a song in the list, it will automatically switch to the current list for playback (only valid for playlists and leaderboards)", "setting_list_click_action": "When you click a song in the list, it will automatically switch to the current list for playback (only valid for playlists and leaderboards)",
"setting_list_show interval": "Show song duration",
"setting_list_show_album_name": "Show song album name",
"setting_lyric_dektop_permission_tip": "The desktop lyrics function needs to be granted the permission of LX Music to display the floating window in the system permission setting before it can be used. Do you go to the relevant interface to grant this permission?", "setting_lyric_dektop_permission_tip": "The desktop lyrics function needs to be granted the permission of LX Music to display the floating window in the system permission setting before it can be used. Do you go to the relevant interface to grant this permission?",
"setting_lyric_desktop": "Desktop lyrics", "setting_lyric_desktop": "Desktop lyrics",
"setting_lyric_desktop_enable": "Show desktop lyrics", "setting_lyric_desktop_enable": "Show desktop lyrics",

View File

@ -212,6 +212,8 @@
"setting_list_add_music_location_type_bottom": "底部", "setting_list_add_music_location_type_bottom": "底部",
"setting_list_add_music_location_type_top": "顶部", "setting_list_add_music_location_type_top": "顶部",
"setting_list_click_action": "点击列表里的歌曲时自动切换到当前列表播放(仅对歌单、排行榜有效)", "setting_list_click_action": "点击列表里的歌曲时自动切换到当前列表播放(仅对歌单、排行榜有效)",
"setting_list_show interval": "显示歌曲时长",
"setting_list_show_album_name": "显示歌曲专辑名",
"setting_lyric_dektop_permission_tip": "桌面歌词功能需要在系统权限设置中授予LX Music显示悬浮窗口的权限才能使用是否去相关界面授予此权限", "setting_lyric_dektop_permission_tip": "桌面歌词功能需要在系统权限设置中授予LX Music显示悬浮窗口的权限才能使用是否去相关界面授予此权限",
"setting_lyric_desktop": "桌面歌词", "setting_lyric_desktop": "桌面歌词",
"setting_lyric_desktop_enable": "显示桌面歌词", "setting_lyric_desktop_enable": "显示桌面歌词",

View File

@ -90,6 +90,7 @@ export default forwardRef<MusicListType, {}>((props, ref) => {
onRefresh={handleRefresh} onRefresh={handleRefresh}
onLoadMore={handleLoadMore} onLoadMore={handleLoadMore}
checkHomePagerIdle checkHomePagerIdle
rowType='medium'
/> />
}) })

View File

@ -8,11 +8,12 @@ import { getListPosition, getListPrevSelectId, saveListPosition } from '@/utils/
// import { useMusicList } from '@/store/list/hook' // import { useMusicList } from '@/store/list/hook'
import { getListMusics, setActiveList } from '@/core/list' import { getListMusics, setActiveList } from '@/core/list'
import ListItem, { ITEM_HEIGHT } from './ListItem' import ListItem, { ITEM_HEIGHT } from './ListItem'
import { createStyle } from '@/utils/tools' import { createStyle, getRowInfo } from '@/utils/tools'
import { usePlayInfo, usePlayMusicInfo } from '@/store/player/hook' import { usePlayInfo, usePlayMusicInfo } from '@/store/player/hook'
import type { Position } from './ListMenu' import type { Position } from './ListMenu'
import type { SelectMode } from './MultipleModeBar' import type { SelectMode } from './MultipleModeBar'
import { useActiveListId } from '@/store/list/hook' import { useActiveListId } from '@/store/list/hook'
import { useSettingValue } from '@/store/setting/hook'
type FlatListType = FlatListProps<LX.Music.MusicInfo> type FlatListType = FlatListProps<LX.Music.MusicInfo>
@ -54,6 +55,9 @@ const List = forwardRef<ListType, ListProps>(({ onShowMenu, onMuiltSelectMode, o
const selectedListRef = useRef<LX.List.ListMusics>([]) const selectedListRef = useRef<LX.List.ListMusics>([])
const currentListIdRef = useRef('') const currentListIdRef = useRef('')
const waitJumpListPositionRef = useRef(false) const waitJumpListPositionRef = useRef(false)
const rowInfo = useRef(getRowInfo())
const isShowAlbumName = useSettingValue('list.isShowAlbumName')
const isShowInterval = useSettingValue('list.isShowInterval')
// console.log('render music list') // console.log('render music list')
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
@ -84,7 +88,7 @@ const List = forwardRef<ListType, ListProps>(({ onShowMenu, onMuiltSelectMode, o
void getListMusics(listState.activeListId).then((list) => { void getListMusics(listState.activeListId).then((list) => {
const index = list.findIndex(m => m.id == info.id) const index = list.findIndex(m => m.id == info.id)
if (index < 0) return if (index < 0) return
flatListRef.current?.scrollToIndex({ index, viewPosition: 0.3, animated: true }) flatListRef.current?.scrollToIndex({ index: Math.floor(index / (rowInfo.current.rowNum ?? 1)), viewPosition: 0.3, animated: true })
}) })
}, },
})) }))
@ -110,7 +114,7 @@ const List = forwardRef<ListType, ListProps>(({ onShowMenu, onMuiltSelectMode, o
waitJumpListPositionRef.current = false waitJumpListPositionRef.current = false
if (playerState.playMusicInfo.listId == id && playerState.playInfo.playIndex > -1) { if (playerState.playMusicInfo.listId == id && playerState.playInfo.playIndex > -1) {
try { try {
flatListRef.current?.scrollToIndex({ index: playerState.playInfo.playIndex, viewPosition: 0.3, animated: false }) flatListRef.current?.scrollToIndex({ index: Math.floor(playerState.playInfo.playIndex / (rowInfo.current.rowNum ?? 1)), viewPosition: 0.3, animated: false })
return return
} catch {} } catch {}
} }
@ -143,7 +147,7 @@ const List = forwardRef<ListType, ListProps>(({ onShowMenu, onMuiltSelectMode, o
if (isUpdateingList) waitJumpListPositionRef.current = true if (isUpdateingList) waitJumpListPositionRef.current = true
else { else {
try { try {
flatListRef.current?.scrollToIndex({ index: playerState.playInfo.playIndex, viewPosition: 0.3, animated: true }) flatListRef.current?.scrollToIndex({ index: Math.floor(playerState.playInfo.playIndex / (rowInfo.current.rowNum ?? 1)), viewPosition: 0.3, animated: true })
} catch {} } catch {}
} }
} }
@ -249,6 +253,9 @@ const List = forwardRef<ListType, ListProps>(({ onShowMenu, onMuiltSelectMode, o
onLongPress={handleLongPress} onLongPress={handleLongPress}
onShowMenu={onShowMenu} onShowMenu={onShowMenu}
selectedList={selectedList} selectedList={selectedList}
rowInfo={rowInfo.current}
isShowAlbumName={isShowAlbumName}
isShowInterval={isShowInterval}
/> />
) )
const getkey: FlatListType['keyExtractor'] = item => item.id const getkey: FlatListType['keyExtractor'] = item => item.id
@ -263,6 +270,8 @@ const List = forwardRef<ListType, ListProps>(({ onShowMenu, onMuiltSelectMode, o
style={styles.list} style={styles.list}
data={currentList} data={currentList}
maxToRenderPerBatch={4} maxToRenderPerBatch={4}
numColumns={rowInfo.current.rowNum}
horizontal={false}
// updateCellsBatchingPeriod={80} // updateCellsBatchingPeriod={80}
windowSize={8} windowSize={8}
removeClippedSubviews={true} removeClippedSubviews={true}

View File

@ -3,7 +3,7 @@ import { View, TouchableOpacity } from 'react-native'
import { LIST_ITEM_HEIGHT } from '@/config/constant' import { LIST_ITEM_HEIGHT } from '@/config/constant'
// import { BorderWidths } from '@/theme' // import { BorderWidths } from '@/theme'
import { Icon } from '@/components/common/Icon' import { Icon } from '@/components/common/Icon'
import { createStyle } from '@/utils/tools' import { createStyle, type RowInfo } from '@/utils/tools'
import { useTheme } from '@/store/theme/hook' import { useTheme } from '@/store/theme/hook'
import { useAssertApiSupport } from '@/store/common/hook' import { useAssertApiSupport } from '@/store/common/hook'
import { scaleSizeH } from '@/utils/pixelRatio' import { scaleSizeH } from '@/utils/pixelRatio'
@ -12,7 +12,8 @@ import Badge from '@/components/common/Badge'
export const ITEM_HEIGHT = scaleSizeH(LIST_ITEM_HEIGHT) export const ITEM_HEIGHT = scaleSizeH(LIST_ITEM_HEIGHT)
export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPress, selectedList }: {
export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPress, selectedList, rowInfo, isShowAlbumName, isShowInterval }: {
item: LX.Music.MusicInfo item: LX.Music.MusicInfo
index: number index: number
activeIndex: number activeIndex: number
@ -20,6 +21,9 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres
onLongPress: (item: LX.Music.MusicInfo, index: number) => void onLongPress: (item: LX.Music.MusicInfo, index: number) => void
onShowMenu: (item: LX.Music.MusicInfo, index: number, position: { x: number, y: number, w: number, h: number }) => void onShowMenu: (item: LX.Music.MusicInfo, index: number, position: { x: number, y: number, w: number, h: number }) => void
selectedList: LX.Music.MusicInfo[] selectedList: LX.Music.MusicInfo[]
rowInfo: RowInfo
isShowAlbumName: boolean
isShowInterval: boolean
}) => { }) => {
const theme = useTheme() const theme = useTheme()
@ -37,8 +41,10 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres
} }
const active = activeIndex == index const active = activeIndex == index
const singer = `${item.singer}${isShowAlbumName && item.meta.albumName ? ` · ${item.meta.albumName}` : ''}`
return ( return (
<View style={{ ...styles.listItem, height: ITEM_HEIGHT, backgroundColor: isSelected ? theme['c-primary-background-hover'] : 'rgba(0,0,0,0)', opacity: isSupported ? 1 : 0.5 }}> <View style={{ ...styles.listItem, width: rowInfo.rowWidth, height: ITEM_HEIGHT, backgroundColor: isSelected ? theme['c-primary-background-hover'] : 'rgba(0,0,0,0)', opacity: isSupported ? 1 : 0.5 }}>
<TouchableOpacity style={styles.listItemLeft} onPress={() => { onPress(item, index) }} onLongPress={() => { onLongPress(item, index) }}> <TouchableOpacity style={styles.listItemLeft} onPress={() => { onPress(item, index) }} onLongPress={() => { onLongPress(item, index) }}>
{ {
active active
@ -50,10 +56,17 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres
<Text color={active ? theme['c-primary-font'] : theme['c-font']} numberOfLines={1}>{item.name}</Text> <Text color={active ? theme['c-primary-font'] : theme['c-font']} numberOfLines={1}>{item.name}</Text>
{/* </View> */} {/* </View> */}
<View style={styles.listItemSingle}> <View style={styles.listItemSingle}>
<Text style={styles.listItemSingleText} size={13} color={active ? theme['c-primary-alpha-200'] : theme['c-500']} numberOfLines={1}>{item.singer}</Text> <Badge>{item.source.toUpperCase()}</Badge>
<Badge>{item.source}</Badge> <Text style={styles.listItemSingleText} size={11} color={active ? theme['c-primary-alpha-200'] : theme['c-500']} numberOfLines={1}>
{singer}
</Text>
</View> </View>
</View> </View>
{
isShowInterval ? (
<Text size={12} color={active ? theme['c-primary-alpha-200'] : theme['c-300']} numberOfLines={1}>{item.interval}</Text>
) : null
}
</TouchableOpacity> </TouchableOpacity>
{/* <View style={styles.listItemRight}> */} {/* <View style={styles.listItemRight}> */}
<TouchableOpacity onPress={handleShowMenu} ref={moreButtonRef} style={styles.moreButton}> <TouchableOpacity onPress={handleShowMenu} ref={moreButtonRef} style={styles.moreButton}>
@ -66,6 +79,8 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres
return !!(prevProps.item === nextProps.item && return !!(prevProps.item === nextProps.item &&
prevProps.index === nextProps.index && prevProps.index === nextProps.index &&
prevProps.activeIndex != nextProps.index && prevProps.activeIndex != nextProps.index &&
prevProps.isShowAlbumName != nextProps.isShowAlbumName &&
prevProps.isShowInterval != nextProps.isShowInterval &&
nextProps.activeIndex != nextProps.index && nextProps.activeIndex != nextProps.index &&
nextProps.selectedList.includes(nextProps.item) == prevProps.selectedList.includes(nextProps.item) nextProps.selectedList.includes(nextProps.item) == prevProps.selectedList.includes(nextProps.item)
) )
@ -74,7 +89,7 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres
const styles = createStyle({ const styles = createStyle({
listItem: { listItem: {
width: '100%', // width: '50%',
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'nowrap', flexWrap: 'nowrap',
// paddingLeft: 10, // paddingLeft: 10,
@ -98,17 +113,18 @@ const styles = createStyle({
paddingRight: 3, paddingRight: 3,
}, },
itemInfo: { itemInfo: {
flexGrow: 0, flexGrow: 1,
flexShrink: 1, flexShrink: 1,
// paddingTop: 10, // paddingTop: 10,
// paddingBottom: 10, // paddingBottom: 10,
paddingRight: 2,
}, },
// listItemTitle: { // listItemTitle: {
// flexGrow: 0, // flexGrow: 0,
// flexShrink: 1, // flexShrink: 1,
// }, // },
listItemSingle: { listItemSingle: {
paddingTop: 2, paddingTop: 3,
flexDirection: 'row', flexDirection: 'row',
// alignItems: 'flex-end', // alignItems: 'flex-end',
}, },
@ -116,14 +132,15 @@ const styles = createStyle({
// backgroundColor: 'rgba(0,0,0,0.2)', // backgroundColor: 'rgba(0,0,0,0.2)',
flexGrow: 0, flexGrow: 0,
flexShrink: 1, flexShrink: 1,
fontWeight: '300',
// fontSize: 15, // fontSize: 15,
}, },
listItemBadge: { // listItemBadge: {
// fontSize: 10, // // fontSize: 10,
paddingLeft: 5, // paddingLeft: 5,
paddingTop: 2, // paddingTop: 2,
alignSelf: 'flex-start', // alignSelf: 'flex-start',
}, // },
listItemRight: { listItemRight: {
flexGrow: 0, flexGrow: 0,
flexShrink: 0, flexShrink: 0,

View File

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

View File

@ -0,0 +1,32 @@
import { updateSetting } from '@/core/common'
import { useI18n } from '@/lang'
import { createStyle } from '@/utils/tools'
import React, { memo } from 'react'
import { View } from 'react-native'
import { useSettingValue } from '@/store/setting/hook'
import CheckBoxItem from '../../components/CheckBoxItem'
export default memo(() => {
const t = useI18n()
const isShowAlbumName = useSettingValue('list.isShowAlbumName')
const setShowAlbumName = (isShowAlbumName: boolean) => {
updateSetting({ 'list.isShowAlbumName': isShowAlbumName })
}
return (
<View style={styles.content}>
<CheckBoxItem check={isShowAlbumName} onChange={setShowAlbumName} label={t('setting_list_show_album_name')} />
</View>
)
})
const styles = createStyle({
content: {
marginTop: 5,
// marginBottom: 15,
},
})

View File

@ -0,0 +1,32 @@
import { updateSetting } from '@/core/common'
import { useI18n } from '@/lang'
import { createStyle } from '@/utils/tools'
import React, { memo } from 'react'
import { View } from 'react-native'
import { useSettingValue } from '@/store/setting/hook'
import CheckBoxItem from '../../components/CheckBoxItem'
export default memo(() => {
const t = useI18n()
const isShowInterval = useSettingValue('list.isShowInterval')
const setShowInterval = (isShowInterval: boolean) => {
updateSetting({ 'list.isShowInterval': isShowInterval })
}
return (
<View style={styles.content}>
<CheckBoxItem check={isShowInterval} onChange={setShowInterval} label={t('setting_list_show interval')} />
</View>
)
})
const styles = createStyle({
content: {
marginTop: 5,
marginBottom: 15,
},
})

View File

@ -3,6 +3,8 @@ import React, { memo } from 'react'
import Section from '../../components/Section' import Section from '../../components/Section'
import AddMusicLocationType from './AddMusicLocationType' import AddMusicLocationType from './AddMusicLocationType'
import IsClickPlayList from './IsClickPlayList' import IsClickPlayList from './IsClickPlayList'
import IsShowAlbumName from './IsShowAlbumName'
import IsShowInterval from './IsShowInterval'
import { useI18n } from '@/lang' import { useI18n } from '@/lang'
@ -12,6 +14,8 @@ export default memo(() => {
return ( return (
<Section title={t('setting_list')}> <Section title={t('setting_list')}>
<IsClickPlayList /> <IsClickPlayList />
<IsShowAlbumName />
<IsShowInterval />
<AddMusicLocationType /> <AddMusicLocationType />
</Section> </Section>
) )

View File

@ -266,6 +266,16 @@ declare global {
*/ */
'list.isShowSource': boolean 'list.isShowSource': boolean
/**
*
*/
'list.isShowAlbumName': boolean
/**
*
*/
'list.isShowInterval': boolean
/** /**
* *
*/ */

View File

@ -423,4 +423,22 @@ export const createStyle = <T extends StyleSheet.NamedStyles<T>>(styles: T | Sty
return StyleSheet.create(newStyle as StyleSheet.NamedStyles<T>) return StyleSheet.create(newStyle as StyleSheet.NamedStyles<T>)
} }
export interface RowInfo {
rowNum: number | undefined
rowWidth: `${number}%`
}
export type RowInfoType = 'full' | 'medium'
export const getRowInfo = (type: RowInfoType = 'full'): RowInfo => {
const win = Dimensions.get('window')
let isMultiRow = win.width > win.height
if (type == 'medium' && win.width / win.height < 1.8) isMultiRow = false
// console.log('getRowInfo')
return {
rowNum: isMultiRow ? 2 : undefined,
rowWidth: isMultiRow ? '50%' : '100%',
}
}
export const toMD5 = stringMd5 export const toMD5 = stringMd5