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 {addFileScheme, addRandomHash} from '@/utils/fileUtils'; 11import Toast from '@/utils/toast'; 12import {hideDialog} from '../useDialog'; 13import Dialog from './base'; 14import Input from '@/components/base/input'; 15import {fontSizeConst} from '@/constants/uiConst'; 16import {copyAsync, deleteAsync, getInfoAsync} from 'expo-file-system'; 17import MusicSheet from '@/core/musicSheet'; 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.updateMusicSheetBase(musicSheet.id, { 85 coverImg: newCoverImg ? addRandomHash(newCoverImg) : undefined, 86 title: _title, 87 }).then(() => { 88 Toast.success('更新歌单信息成功~'); 89 }); 90 hideDialog(); 91 } 92 93 return ( 94 <Dialog onDismiss={hideDialog}> 95 <Dialog.Content> 96 <View style={style.row}> 97 <ThemeText>封面</ThemeText> 98 <TouchableOpacity 99 onPress={onChangeCoverPress} 100 onLongPress={() => { 101 setCoverImg(undefined); 102 }}> 103 <Image 104 style={style.coverImg} 105 uri={coverImg} 106 emptySrc={ImgAsset.albumDefault} 107 /> 108 </TouchableOpacity> 109 </View> 110 <View style={style.row}> 111 <ThemeText>歌单名</ThemeText> 112 <Input 113 numberOfLines={1} 114 textAlign="right" 115 value={title} 116 hasHorizontalPadding={false} 117 onChangeText={onTitleChange} 118 style={{ 119 height: fontSizeConst.content * 2.5, 120 width: '50%', 121 borderBottomWidth: 1, 122 includeFontPadding: false, 123 borderBottomColor: colors.text, 124 }} 125 /> 126 </View> 127 </Dialog.Content> 128 <Dialog.Actions 129 actions={[ 130 { 131 title: '取消', 132 type: 'normal', 133 onPress: hideDialog, 134 }, 135 { 136 title: '确认', 137 type: 'primary', 138 onPress: onConfirm, 139 }, 140 ]} 141 /> 142 </Dialog> 143 ); 144} 145 146const style = StyleSheet.create({ 147 row: { 148 marginTop: rpx(28), 149 height: rpx(120), 150 flexDirection: 'row', 151 justifyContent: 'space-between', 152 alignItems: 'center', 153 paddingBottom: rpx(12), 154 }, 155 coverImg: { 156 width: rpx(100), 157 height: rpx(100), 158 borderRadius: rpx(28), 159 }, 160}); 161