1import React from 'react'; 2import {StyleSheet, View} from 'react-native'; 3import rpx from '@/utils/rpx'; 4import {List} from 'react-native-paper'; 5import Tag from './tag'; 6import ThemeText from './themeText'; 7import Image from './image'; 8import IconButton from './iconButton'; 9import FastImage from './fastImage'; 10 11export interface ILeftProps { 12 /** 序号 */ 13 index?: number | string; 14 /** 封面图 */ 15 artwork?: string; 16 /** 封面图的兜底 */ 17 fallback?: any; 18 /** icon */ 19 icon?: Parameters<typeof IconButton>[0]; 20 /** 宽度 */ 21 width?: number; 22 /** 组件 */ 23 component?: () => JSX.Element; 24} 25 26function Left(props?: ILeftProps) { 27 const { 28 index, 29 artwork, 30 fallback, 31 icon, 32 width = rpx(100), 33 component: Component, 34 } = props ?? {}; 35 36 return props && Object.keys(props).length ? ( 37 Component ? ( 38 <Component></Component> 39 ) : ( 40 <View style={[leftStyle.artworkWrapper, {width}]}> 41 {index !== undefined ? ( 42 <ThemeText fontColor="secondary" style={{fontStyle: 'italic'}}> 43 {index} 44 </ThemeText> 45 ) : icon !== undefined ? ( 46 <IconButton {...icon}></IconButton> 47 ) : ( 48 <FastImage 49 style={leftStyle.artwork} 50 uri={artwork?.startsWith('//') ? `https:${artwork}` : artwork} 51 emptySrc={fallback}></FastImage> 52 )} 53 </View> 54 ) 55 ) : ( 56 <></> 57 ); 58} 59 60const leftStyle = StyleSheet.create({ 61 artworkWrapper: { 62 justifyContent: 'center', 63 alignItems: 'center', 64 }, 65 artwork: { 66 width: rpx(76), 67 height: rpx(76), 68 borderRadius: rpx(16), 69 }, 70}); 71 72/** 歌单item */ 73interface IListItemProps { 74 /** 标题 */ 75 title: string | number; 76 /** 描述 */ 77 desc?: string | JSX.Element; 78 /** 标签 */ 79 tag?: string; 80 left?: ILeftProps; 81 /** 右侧按钮 */ 82 right?: () => JSX.Element; 83 itemPaddingHorizontal?: number; 84 itemHeight?: number; 85 onPress?: () => void; 86} 87 88export default function ListItem(props: IListItemProps) { 89 const { 90 title, 91 desc, 92 tag, 93 right, 94 itemHeight, 95 onPress, 96 left, 97 itemPaddingHorizontal = rpx(24), 98 } = props; 99 return ( 100 <List.Item 101 left={() => <Left {...(left ?? {})}></Left>} 102 style={[ 103 style.wrapper, 104 { 105 paddingHorizontal: itemPaddingHorizontal, 106 height: itemHeight ?? rpx(120), 107 paddingVertical: 0, 108 }, 109 ]} 110 title={() => ( 111 <View 112 style={{ 113 alignItems: 'stretch', 114 justifyContent: 'center', 115 height: itemHeight ?? rpx(120), 116 marginRight: right ? rpx(18) : 0, 117 }}> 118 <View style={style.titleWrapper}> 119 <ThemeText numberOfLines={1} style={style.textWidth}> 120 {title} 121 </ThemeText> 122 {tag ? <Tag tagName={tag}></Tag> : <></>} 123 </View> 124 {desc ? ( 125 <ThemeText 126 fontColor="secondary" 127 fontSize="description" 128 numberOfLines={1} 129 style={[style.textWidth, {marginTop: rpx(18)}]}> 130 {desc} 131 </ThemeText> 132 ) : ( 133 <></> 134 )} 135 </View> 136 )} 137 titleStyle={{ 138 paddingVertical: 0, 139 marginLeft: 0, 140 marginVertical: 0, 141 }} 142 right={right ? right : () => <></>} 143 onPress={onPress}></List.Item> 144 ); 145} 146const style = StyleSheet.create({ 147 wrapper: { 148 justifyContent: 'center', 149 }, 150 titleWrapper: { 151 flexDirection: 'row', 152 alignItems: 'center', 153 justifyContent: 'space-between', 154 }, 155 textWidth: { 156 maxWidth: rpx(460), 157 }, 158 artworkWrapper: { 159 width: rpx(76), 160 justifyContent: 'center', 161 alignItems: 'center', 162 marginRight: rpx(12), 163 }, 164 artwork: { 165 width: rpx(76), 166 height: rpx(76), 167 borderRadius: rpx(16), 168 }, 169}); 170