xref: /MusicFree/src/components/panels/types/editMusicSheetInfo.tsx (revision b805fd21ba256105d9b08bc1b9c6e50c8b149adb)
1import React, { useState } from "react";
2import { StyleSheet, TouchableOpacity, View } from "react-native";
3import rpx from "@/utils/rpx";
4import PanelFullscreen from "@/components/panels/base/panelFullscreen.tsx";
5import { hidePanel } from "@/components/panels/usePanel.ts";
6import ThemeText from "@/components/base/themeText.tsx";
7import Toast from "@/utils/toast.ts";
8import useColors from "@/hooks/useColors.ts";
9import MusicSheet from "@/core/musicSheet";
10import Input from "@/components/base/input.tsx";
11import { fontSizeConst } from "@/constants/uiConst.ts";
12import AppBar from "@/components/base/appBar.tsx";
13import globalStyle from "@/constants/globalStyle.ts";
14import VerticalSafeAreaView from "@/components/base/verticalSafeAreaView.tsx";
15import Image from "@/components/base/image.tsx";
16import { ImgAsset } from "@/constants/assetsConst.ts";
17import { launchImageLibrary } from "react-native-image-picker";
18import { addFileScheme, addRandomHash } from "@/utils/fileUtils.ts";
19import pathConst from "@/constants/pathConst.ts";
20import { readAsStringAsync } from "expo-file-system";
21import { exists, unlink, writeFile } from "react-native-fs";
22
23interface IEditSheetDetailProps {
24  musicSheet: IMusic.IMusicSheetItem;
25}
26
27export default function EditMusicSheetInfo(props: IEditSheetDetailProps) {
28  const { musicSheet } = props;
29  const colors = useColors();
30
31  const [coverImg, setCoverImg] = useState(musicSheet?.coverImg);
32  const [title, setTitle] = useState(musicSheet?.title);
33
34  const onChangeCoverPress = async () => {
35      try {
36          const result = await launchImageLibrary({
37              mediaType: 'photo',
38          });
39          const uri = result.assets?.[0].uri;
40          if (!uri) {
41              return;
42          }
43          console.log(uri);
44          setCoverImg(uri);
45      } catch (e) {
46          console.log(e);
47      }
48  };
49
50  function onTitleChange(_: string) {
51    setTitle(_);
52  }
53
54  async function onConfirm() {
55    // 判断是否相同
56    if (
57      coverImg === musicSheet?.coverImg &&
58      title === musicSheet?.title
59    ) {
60      hidePanel();
61      return;
62    }
63
64    let newCoverImg = coverImg;
65    if (coverImg && coverImg !== musicSheet?.coverImg) {
66        newCoverImg = addFileScheme(
67          `${pathConst.dataPath}sheet${musicSheet.id}${coverImg.substring(
68            coverImg.lastIndexOf('.'),
69          )}`,
70        );
71        try {
72          if ((await exists(newCoverImg))) {
73            await unlink(newCoverImg);
74          }
75
76          // Copy
77          const rawImage = await readAsStringAsync(coverImg, {
78            encoding: 'base64'
79          });
80          await writeFile(newCoverImg, rawImage, 'base64');
81        } catch (e) {
82            console.log(e);
83        }
84    }
85    let _title = title;
86    if (!_title?.length) {
87      _title = musicSheet.title;
88    }
89    // 更新歌单信息
90    MusicSheet.updateMusicSheetBase(musicSheet.id, {
91      coverImg: newCoverImg ? addRandomHash(newCoverImg) : undefined,
92      title: _title
93    }).then(() => {
94      Toast.success("更新歌单信息成功~");
95    });
96    hidePanel();
97  }
98
99  return (
100    <PanelFullscreen>
101      <VerticalSafeAreaView style={globalStyle.fwflex1}>
102        <AppBar onBackPress={hidePanel} withStatusBar>
103          编辑歌单信息
104        </AppBar>
105        <View style={style.row}>
106            <ThemeText>封面</ThemeText>
107            <TouchableOpacity
108                onPress={onChangeCoverPress}
109                onLongPress={() => {
110                    setCoverImg(undefined);
111                }}>
112                <Image
113                    style={style.coverImg}
114                    uri={coverImg}
115                    emptySrc={ImgAsset.albumDefault}
116                />
117            </TouchableOpacity>
118        </View>
119        <View style={style.row}>
120          <ThemeText>歌单名</ThemeText>
121          <Input
122            numberOfLines={1}
123            textAlign="right"
124            value={title}
125            hasHorizontalPadding={false}
126            onChangeText={onTitleChange}
127            style={{
128              height: fontSizeConst.content * 2.5,
129              width: "50%",
130              borderBottomWidth: 1,
131              includeFontPadding: false,
132              borderBottomColor: colors.text
133            }}
134          />
135        </View>
136        <TouchableOpacity
137          activeOpacity={0.6}
138          onPress={onConfirm}
139          style={[
140            {
141              backgroundColor: colors.primary
142            },
143            style.button
144          ]}>
145          <ThemeText color={"white"}>确认</ThemeText>
146        </TouchableOpacity>
147      </VerticalSafeAreaView>
148    </PanelFullscreen>
149  );
150}
151
152const style = StyleSheet.create({
153  row: {
154    marginTop: rpx(28),
155    height: rpx(120),
156    flexDirection: "row",
157    justifyContent: "space-between",
158    alignItems: "center",
159    paddingBottom: rpx(12),
160    paddingHorizontal: rpx(24)
161  },
162  coverImg: {
163    width: rpx(100),
164    height: rpx(100),
165    borderRadius: rpx(28)
166  },
167  button: {
168    marginHorizontal: rpx(24),
169    borderRadius: rpx(8),
170    height: rpx(72),
171    marginTop: rpx(24),
172    justifyContent: "center",
173    alignItems: "center"
174  }
175});
176