From 2b83d2126bf15681aee6712aaf5b116e47f00abd Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 19 Aug 2023 10:24:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=97=E8=A1=A8=E5=B8=83?= =?UTF-8?q?=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 9 +++- src/components/OnlineList/List.tsx | 17 ++++++- src/components/OnlineList/ListItem.tsx | 32 ++++++++++--- src/components/OnlineList/index.tsx | 5 ++- src/components/common/Badge.tsx | 3 +- src/config/defaultSetting.ts | 2 + src/lang/en_us.json | 2 + src/lang/zh_cn.json | 2 + .../Home/Views/Leaderboard/MusicList.tsx | 1 + .../Home/Views/Mylist/MusicList/List.tsx | 17 +++++-- .../Home/Views/Mylist/MusicList/ListItem.tsx | 45 +++++++++++++------ .../Setting/settings/List/IsClickPlayList.tsx | 2 +- .../Setting/settings/List/IsShowAlbumName.tsx | 32 +++++++++++++ .../Setting/settings/List/IsShowInterval.tsx | 32 +++++++++++++ .../Views/Setting/settings/List/index.tsx | 4 ++ src/types/app_setting.d.ts | 10 +++++ src/utils/tools.ts | 18 ++++++++ 17 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 src/screens/Home/Views/Setting/settings/List/IsShowAlbumName.tsx create mode 100644 src/screens/Home/Views/Setting/settings/List/IsShowInterval.tsx diff --git a/publish/changeLog.md b/publish/changeLog.md index ec7a319..4965d87 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -6,12 +6,19 @@ ### 不兼容性变更 -该版本修改了同步协议逻辑,至少需要PC端v2.4.0或移动端v1.0.7版本才能连接使用。 +该版本修改了同步协议逻辑,同步功能至少需要PC端v2.4.0或移动端v1.1.0或同步服务v2.0.0版本才能连接使用 + +### 新增 + +- 新增列表设置-是否显示歌曲专辑名,默认关闭 +- 新增列表设置-是否显示歌曲时长,默认开启 ### 优化 - 优化歌单列表歌单封面大小计算方式 - 调整竖屏下的排行榜布局 +- 调整歌曲列表信息布局 +- 调整横屏下的歌曲列表为两列 - 调整桌面歌词主题配色,增强歌词字体阴影(#276) - 优化数据传输逻辑,列表同步指令使用队列机制,保证列表同步操作的顺序 diff --git a/src/components/OnlineList/List.tsx b/src/components/OnlineList/List.tsx index a826847..a3ff750 100644 --- a/src/components/OnlineList/List.tsx +++ b/src/components/OnlineList/List.tsx @@ -3,7 +3,7 @@ import { FlatList, type FlatListProps, RefreshControl, View } from 'react-native // import { useMusicList } from '@/store/list/hook' 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 { SelectMode } from './MultipleModeBar' import { useTheme } from '@/store/theme/hook' @@ -12,9 +12,14 @@ import { MULTI_SELECT_BAR_HEIGHT } from './MultipleModeBar' import { useI18n } from '@/lang' import Text from '@/components/common/Text' import { handlePlay } from './listAction' +import { useSettingValue } from '@/store/setting/hook' type FlatListType = FlatListProps +export type { + RowInfoType, +} + export interface ListProps { onShowMenu: (musicInfo: LX.Music.MusicInfoOnline, index: number, position: Position) => void onMuiltSelectMode: () => void @@ -25,6 +30,7 @@ export interface ListProps { progressViewOffset?: number ListHeaderComponent?: FlatListType['ListEmptyComponent'] checkHomePagerIdle: boolean + rowType?: RowInfoType } export interface ListType { setList: (list: LX.Music.MusicInfoOnline[], isAppend: boolean, showSource: boolean) => void @@ -48,6 +54,7 @@ const List = forwardRef(({ progressViewOffset, ListHeaderComponent, checkHomePagerIdle, + rowType, }, ref) => { // const t = useI18n() const theme = useTheme() @@ -61,6 +68,9 @@ const List = forwardRef(({ const selectedListRef = useRef([]) const [visibleMultiSelect, setVisibleMultiSelect] = useState(false) const [status, setStatus] = useState('idle') + const rowInfo = useRef(getRowInfo(rowType)) + const isShowAlbumName = useSettingValue('list.isShowAlbumName') + const isShowInterval = useSettingValue('list.isShowInterval') // const currentListIdRef = useRef('') // console.log('render music list') @@ -179,6 +189,9 @@ const List = forwardRef(({ onLongPress={handleLongPress} onShowMenu={onShowMenu} selectedList={selectedList} + rowInfo={rowInfo.current} + isShowAlbumName={isShowAlbumName} + isShowInterval={isShowInterval} /> ) const getkey: FlatListType['keyExtractor'] = item => item.id @@ -221,6 +234,8 @@ const List = forwardRef(({ ref={flatListRef} style={styles.list} data={currentList} + numColumns={rowInfo.current.rowNum} + horizontal={false} maxToRenderPerBatch={4} // updateCellsBatchingPeriod={80} windowSize={8} diff --git a/src/components/OnlineList/ListItem.tsx b/src/components/OnlineList/ListItem.tsx index 85927c4..d06965d 100644 --- a/src/components/OnlineList/ListItem.tsx +++ b/src/components/OnlineList/ListItem.tsx @@ -1,5 +1,5 @@ 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 Text from '@/components/common/Text' import Badge, { type BadgeType } from '@/components/common/Badge' @@ -8,6 +8,7 @@ import { useI18n } from '@/lang' import { useTheme } from '@/store/theme/hook' import { scaleSizeH } from '@/utils/pixelRatio' import { LIST_ITEM_HEIGHT } from '@/config/constant' +import { createStyle, type RowInfo } from '@/utils/tools' export const ITEM_HEIGHT = scaleSizeH(LIST_ITEM_HEIGHT) @@ -28,7 +29,7 @@ const useQualityTag = (musicInfo: LX.Music.MusicInfoOnline) => { 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 index: number showSource?: boolean @@ -36,6 +37,9 @@ export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu 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 selectedList: LX.Music.MusicInfoOnline[] + rowInfo: RowInfo + isShowAlbumName: boolean + isShowInterval: boolean }) => { const theme = useTheme() @@ -52,18 +56,25 @@ export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu } const tagInfo = useQualityTag(item) + const singer = `${item.singer}${isShowAlbumName && item.meta.albumName ? ` · ${item.meta.albumName}` : ''}` + return ( - + { onPress(item, index) }} onLongPress={() => { onLongPress(item, index) }}> {index + 1} {item.name} - {item.singer} { tagInfo.type ? {tagInfo.text} : null } { showSource ? {item.source} : null } + {singer} + { + isShowInterval ? ( + {item.interval} + ) : null + } @@ -77,9 +88,9 @@ export default memo(({ item, index, showSource, onPress, onLongPress, onShowMenu ) }) -const styles = StyleSheet.create({ +const styles = createStyle({ listItem: { - width: '100%', + // width: '100%', flexDirection: 'row', flexWrap: 'nowrap', // paddingLeft: 10, @@ -103,8 +114,9 @@ const styles = StyleSheet.create({ paddingRight: 3, }, itemInfo: { - flexGrow: 0, + flexGrow: 1, flexShrink: 1, + paddingRight: 2, // paddingTop: 10, // paddingBottom: 10, }, @@ -117,14 +129,20 @@ const styles = StyleSheet.create({ listItemSingle: { paddingTop: 2, flexDirection: 'row', + alignItems: 'center', // alignItems: 'flex-end', // backgroundColor: 'rgba(0,0,0,0.2)', }, + listItemTimeLabel: { + marginRight: 5, + fontWeight: '400', + }, listItemSingleText: { // fontSize: 13, // paddingTop: 2, flexGrow: 0, flexShrink: 1, + fontWeight: '300', }, listItemBadge: { // fontSize: 10, diff --git a/src/components/OnlineList/index.tsx b/src/components/OnlineList/index.tsx index ed3e176..358f878 100644 --- a/src/components/OnlineList/index.tsx +++ b/src/components/OnlineList/index.tsx @@ -1,7 +1,7 @@ import React, { useRef, forwardRef, useImperativeHandle } from 'react' import { View } from 'react-native' // 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 ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal' import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal' @@ -16,6 +16,7 @@ export interface OnlineListProps { progressViewOffset?: ListProps['progressViewOffset'] ListHeaderComponent?: ListProps['ListHeaderComponent'] checkHomePagerIdle?: boolean + rowType?: RowInfoType } export interface OnlineListType { setList: (list: LX.Music.MusicInfoOnline[], isAppend?: boolean, showSource?: boolean) => void @@ -29,6 +30,7 @@ export default forwardRef(({ progressViewOffset, ListHeaderComponent, checkHomePagerIdle = false, + rowType, }, ref) => { const listRef = useRef(null) const multipleModeBarRef = useRef(null) @@ -90,6 +92,7 @@ export default forwardRef(({ progressViewOffset={progressViewOffset} ListHeaderComponent={ListHeaderComponent} checkHomePagerIdle={checkHomePagerIdle} + rowType={rowType} /> ((props, ref) => { onRefresh={handleRefresh} onLoadMore={handleLoadMore} checkHomePagerIdle + rowType='medium' /> }) diff --git a/src/screens/Home/Views/Mylist/MusicList/List.tsx b/src/screens/Home/Views/Mylist/MusicList/List.tsx index 65f7291..da32ad2 100644 --- a/src/screens/Home/Views/Mylist/MusicList/List.tsx +++ b/src/screens/Home/Views/Mylist/MusicList/List.tsx @@ -8,11 +8,12 @@ import { getListPosition, getListPrevSelectId, saveListPosition } from '@/utils/ // import { useMusicList } from '@/store/list/hook' import { getListMusics, setActiveList } from '@/core/list' 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 type { Position } from './ListMenu' import type { SelectMode } from './MultipleModeBar' import { useActiveListId } from '@/store/list/hook' +import { useSettingValue } from '@/store/setting/hook' type FlatListType = FlatListProps @@ -54,6 +55,9 @@ const List = forwardRef(({ onShowMenu, onMuiltSelectMode, o const selectedListRef = useRef([]) const currentListIdRef = useRef('') const waitJumpListPositionRef = useRef(false) + const rowInfo = useRef(getRowInfo()) + const isShowAlbumName = useSettingValue('list.isShowAlbumName') + const isShowInterval = useSettingValue('list.isShowInterval') // console.log('render music list') useImperativeHandle(ref, () => ({ @@ -84,7 +88,7 @@ const List = forwardRef(({ onShowMenu, onMuiltSelectMode, o void getListMusics(listState.activeListId).then((list) => { const index = list.findIndex(m => m.id == info.id) 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(({ onShowMenu, onMuiltSelectMode, o waitJumpListPositionRef.current = false if (playerState.playMusicInfo.listId == id && playerState.playInfo.playIndex > -1) { 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 } catch {} } @@ -143,7 +147,7 @@ const List = forwardRef(({ onShowMenu, onMuiltSelectMode, o if (isUpdateingList) waitJumpListPositionRef.current = true else { 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 {} } } @@ -249,6 +253,9 @@ const List = forwardRef(({ onShowMenu, onMuiltSelectMode, o onLongPress={handleLongPress} onShowMenu={onShowMenu} selectedList={selectedList} + rowInfo={rowInfo.current} + isShowAlbumName={isShowAlbumName} + isShowInterval={isShowInterval} /> ) const getkey: FlatListType['keyExtractor'] = item => item.id @@ -263,6 +270,8 @@ const List = forwardRef(({ onShowMenu, onMuiltSelectMode, o style={styles.list} data={currentList} maxToRenderPerBatch={4} + numColumns={rowInfo.current.rowNum} + horizontal={false} // updateCellsBatchingPeriod={80} windowSize={8} removeClippedSubviews={true} diff --git a/src/screens/Home/Views/Mylist/MusicList/ListItem.tsx b/src/screens/Home/Views/Mylist/MusicList/ListItem.tsx index e37d2eb..fdc2c4c 100644 --- a/src/screens/Home/Views/Mylist/MusicList/ListItem.tsx +++ b/src/screens/Home/Views/Mylist/MusicList/ListItem.tsx @@ -3,7 +3,7 @@ import { View, TouchableOpacity } from 'react-native' import { LIST_ITEM_HEIGHT } from '@/config/constant' // import { BorderWidths } from '@/theme' 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 { useAssertApiSupport } from '@/store/common/hook' import { scaleSizeH } from '@/utils/pixelRatio' @@ -12,7 +12,8 @@ import Badge from '@/components/common/Badge' 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 index: number activeIndex: number @@ -20,6 +21,9 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres 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 selectedList: LX.Music.MusicInfo[] + rowInfo: RowInfo + isShowAlbumName: boolean + isShowInterval: boolean }) => { const theme = useTheme() @@ -37,8 +41,10 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres } const active = activeIndex == index + const singer = `${item.singer}${isShowAlbumName && item.meta.albumName ? ` · ${item.meta.albumName}` : ''}` + return ( - + { onPress(item, index) }} onLongPress={() => { onLongPress(item, index) }}> { active @@ -50,10 +56,17 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres {item.name} {/* */} - {item.singer} - {item.source} + {item.source.toUpperCase()} + + {singer} + + { + isShowInterval ? ( + {item.interval} + ) : null + } {/* */} @@ -66,6 +79,8 @@ export default memo(({ item, index, activeIndex, onPress, onShowMenu, onLongPres return !!(prevProps.item === nextProps.item && prevProps.index === nextProps.index && prevProps.activeIndex != nextProps.index && + prevProps.isShowAlbumName != nextProps.isShowAlbumName && + prevProps.isShowInterval != nextProps.isShowInterval && nextProps.activeIndex != nextProps.index && 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({ listItem: { - width: '100%', + // width: '50%', flexDirection: 'row', flexWrap: 'nowrap', // paddingLeft: 10, @@ -98,17 +113,18 @@ const styles = createStyle({ paddingRight: 3, }, itemInfo: { - flexGrow: 0, + flexGrow: 1, flexShrink: 1, // paddingTop: 10, // paddingBottom: 10, + paddingRight: 2, }, // listItemTitle: { // flexGrow: 0, // flexShrink: 1, // }, listItemSingle: { - paddingTop: 2, + paddingTop: 3, flexDirection: 'row', // alignItems: 'flex-end', }, @@ -116,14 +132,15 @@ const styles = createStyle({ // backgroundColor: 'rgba(0,0,0,0.2)', flexGrow: 0, flexShrink: 1, + fontWeight: '300', // fontSize: 15, }, - listItemBadge: { - // fontSize: 10, - paddingLeft: 5, - paddingTop: 2, - alignSelf: 'flex-start', - }, + // listItemBadge: { + // // fontSize: 10, + // paddingLeft: 5, + // paddingTop: 2, + // alignSelf: 'flex-start', + // }, listItemRight: { flexGrow: 0, flexShrink: 0, diff --git a/src/screens/Home/Views/Setting/settings/List/IsClickPlayList.tsx b/src/screens/Home/Views/Setting/settings/List/IsClickPlayList.tsx index d6e4de2..cddfd56 100644 --- a/src/screens/Home/Views/Setting/settings/List/IsClickPlayList.tsx +++ b/src/screens/Home/Views/Setting/settings/List/IsClickPlayList.tsx @@ -26,7 +26,7 @@ export default memo(() => { const styles = createStyle({ content: { marginTop: 5, - marginBottom: 15, + // marginBottom: 15, }, }) diff --git a/src/screens/Home/Views/Setting/settings/List/IsShowAlbumName.tsx b/src/screens/Home/Views/Setting/settings/List/IsShowAlbumName.tsx new file mode 100644 index 0000000..848a2c5 --- /dev/null +++ b/src/screens/Home/Views/Setting/settings/List/IsShowAlbumName.tsx @@ -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 ( + + + + ) +}) + + +const styles = createStyle({ + content: { + marginTop: 5, + // marginBottom: 15, + }, +}) + diff --git a/src/screens/Home/Views/Setting/settings/List/IsShowInterval.tsx b/src/screens/Home/Views/Setting/settings/List/IsShowInterval.tsx new file mode 100644 index 0000000..573ba80 --- /dev/null +++ b/src/screens/Home/Views/Setting/settings/List/IsShowInterval.tsx @@ -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 ( + + + + ) +}) + + +const styles = createStyle({ + content: { + marginTop: 5, + marginBottom: 15, + }, +}) + diff --git a/src/screens/Home/Views/Setting/settings/List/index.tsx b/src/screens/Home/Views/Setting/settings/List/index.tsx index fc4e4e9..71ead3c 100644 --- a/src/screens/Home/Views/Setting/settings/List/index.tsx +++ b/src/screens/Home/Views/Setting/settings/List/index.tsx @@ -3,6 +3,8 @@ import React, { memo } from 'react' import Section from '../../components/Section' import AddMusicLocationType from './AddMusicLocationType' import IsClickPlayList from './IsClickPlayList' +import IsShowAlbumName from './IsShowAlbumName' +import IsShowInterval from './IsShowInterval' import { useI18n } from '@/lang' @@ -12,6 +14,8 @@ export default memo(() => { return (
+ +
) diff --git a/src/types/app_setting.d.ts b/src/types/app_setting.d.ts index 67afd4a..ebe8963 100644 --- a/src/types/app_setting.d.ts +++ b/src/types/app_setting.d.ts @@ -266,6 +266,16 @@ declare global { */ 'list.isShowSource': boolean + /** + * 是否显示歌曲专辑名 + */ + 'list.isShowAlbumName': boolean + + /** + * 是否显示歌曲时长 + */ + 'list.isShowInterval': boolean + /** * 是否自动恢复列表滚动位置(仅对我的列表有效) */ diff --git a/src/utils/tools.ts b/src/utils/tools.ts index 1cdc1d2..b3f7c8d 100644 --- a/src/utils/tools.ts +++ b/src/utils/tools.ts @@ -423,4 +423,22 @@ export const createStyle = >(styles: T | Sty return StyleSheet.create(newStyle as StyleSheet.NamedStyles) } +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