1import React, {useState} from 'react'; 2import useColors from '@/hooks/useColors'; 3import rpx from '@/utils/rpx'; 4import {StyleSheet, TouchableOpacity, View} from 'react-native'; 5import ThemeText from '@/components/base/themeText'; 6import {ImgAsset} from '@/constants/assetsConst'; 7import {launchImageLibrary} from 'react-native-image-picker'; 8import pathConst from '@/constants/pathConst'; 9import Image from '@/components/base/image'; 10import MusicSheet from '@/core/musicSheet'; 11import {addFileScheme, addRandomHash} from '@/utils/fileUtils'; 12import Toast from '@/utils/toast'; 13import {hideDialog} from '../useDialog'; 14import Dialog from './base'; 15import Input from '@/components/base/input'; 16import {fontSizeConst} from '@/constants/uiConst'; 17import {copyAsync, deleteAsync, getInfoAsync} from 'expo-file-system'; 18 19interface IEditSheetDetailProps { 20 musicSheet: IMusic.IMusicSheetItem; 21} 22export default function EditSheetDetailDialog(props: IEditSheetDetailProps) { 23 const {musicSheet} = props; 24 const colors = useColors(); 25 26 const [coverImg, setCoverImg] = useState(musicSheet?.coverImg); 27 const [title, setTitle] = useState(musicSheet?.title); 28 29 // onCover 30 31 const onChangeCoverPress = async () => { 32 try { 33 const result = await launchImageLibrary({ 34 mediaType: 'photo', 35 }); 36 const uri = result.assets?.[0].uri; 37 if (!uri) { 38 return; 39 } 40 console.log(uri); 41 setCoverImg(uri); 42 } catch (e) { 43 console.log(e); 44 } 45 }; 46 47 function onTitleChange(_: string) { 48 setTitle(_); 49 } 50 51 async function onConfirm() { 52 // 判断是否相同 53 if (coverImg === musicSheet?.coverImg && title === musicSheet?.title) { 54 hideDialog(); 55 return; 56 } 57 58 let newCoverImg = coverImg; 59 if (coverImg && coverImg !== musicSheet?.coverImg) { 60 newCoverImg = addFileScheme( 61 `${pathConst.dataPath}sheet${musicSheet.id}${coverImg.substring( 62 coverImg.lastIndexOf('.'), 63 )}`, 64 ); 65 try { 66 if ((await getInfoAsync(newCoverImg)).exists) { 67 await deleteAsync(newCoverImg, { 68 idempotent: true, // 报错时不抛异常 69 }); 70 } 71 await copyAsync({ 72 from: coverImg, 73 to: newCoverImg, 74 }); 75 } catch (e) { 76 console.log(e); 77 } 78 } 79 let _title = title; 80 if (!_title?.length) { 81 _title = musicSheet.title; 82 } 83 // 更新歌单信息 84 MusicSheet.updateAndSaveSheet(musicSheet.id, { 85 basic: { 86 coverImg: newCoverImg ? addRandomHash(newCoverImg) : undefined, 87 title: _title, 88 }, 89 }).then(() => { 90 Toast.success('更新歌单信息成功~'); 91 }); 92 hideDialog(); 93 } 94 95 return ( 96 <Dialog onDismiss={hideDialog}> 97 <Dialog.Content> 98 <View style={style.row}> 99 <ThemeText>封面</ThemeText> 100 <TouchableOpacity 101 onPress={onChangeCoverPress} 102 onLongPress={() => { 103 setCoverImg(undefined); 104 }}> 105 <Image 106 style={style.coverImg} 107 uri={coverImg} 108 emptySrc={ImgAsset.albumDefault} 109 /> 110 </TouchableOpacity> 111 </View> 112 <View style={style.row}> 113 <ThemeText>歌单名</ThemeText> 114 <Input 115 numberOfLines={1} 116 textAlign="right" 117 value={title} 118 hasHorizonalPadding={false} 119 onChangeText={onTitleChange} 120 style={{ 121 height: fontSizeConst.content * 2.5, 122 width: '50%', 123 borderBottomWidth: 1, 124 includeFontPadding: false, 125 borderBottomColor: colors.text, 126 }} 127 /> 128 </View> 129 </Dialog.Content> 130 <Dialog.Actions 131 actions={[ 132 { 133 title: '取消', 134 type: 'normal', 135 onPress: hideDialog, 136 }, 137 { 138 title: '确认', 139 type: 'primary', 140 onPress: onConfirm, 141 }, 142 ]} 143 /> 144 </Dialog> 145 ); 146} 147 148const style = StyleSheet.create({ 149 row: { 150 marginTop: rpx(28), 151 height: rpx(120), 152 flexDirection: 'row', 153 justifyContent: 'space-between', 154 alignItems: 'center', 155 paddingBottom: rpx(12), 156 }, 157 coverImg: { 158 width: rpx(100), 159 height: rpx(100), 160 borderRadius: rpx(28), 161 }, 162}); 163