Skip to content

Commit

Permalink
feat: remove react native file access
Browse files Browse the repository at this point in the history
  • Loading branch information
maotoumao committed Aug 6, 2024
1 parent c68331a commit 5353b47
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 43 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"dayjs": "^1.11.12",
"deepmerge": "^4.3.1",
"expo": "^51.0.0",
"expo-file-system": "^17.0.1",
"expo-splash-screen": "~0.27.5",
"he": "^1.2.0",
"immer": "^10.1.1",
Expand All @@ -60,7 +61,6 @@
"react-native-device-info": "^11.1.0",
"react-native-document-picker": "^9.3.0",
"react-native-fast-image": "^8.6.3",
"react-native-file-access": "^3.1.0",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "^2.18.1",
"react-native-get-random-values": "^1.11.0",
Expand Down
2 changes: 1 addition & 1 deletion src/components/panels/types/musicItemOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ export default function MusicItemOptions(props: IMusicItemOptionsProps) {
<ListItem.ListItemIcon
width={rpx(48)}
icon={item.icon}
iconSize={iconSizeConst.small}
iconSize={iconSizeConst.light}
/>
<ListItem.Content title={item.title} />
</ListItem>
Expand Down
61 changes: 35 additions & 26 deletions src/core/localMusicSheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import StateMapper from '@/utils/stateMapper';
import {getStorage, setStorage} from '@/utils/storage';
import {nanoid} from 'nanoid';
import {useEffect, useState} from 'react';
import {FileStat, FileSystem} from 'react-native-file-access';
import {unlink} from 'react-native-fs';
import {getInfoAsync, readDirectoryAsync} from 'expo-file-system';
import {addFileScheme, getFileName} from '@/utils/fileUtils.ts';

let localSheet: IMusic.IMusicItem[] = [];
const localSheetStateMapper = new StateMapper(() => localSheet);
Expand All @@ -28,7 +29,7 @@ export async function setup() {
musicItem,
InternalDataType.LOCALPATH,
);
if (localPath && (await FileSystem.exists(localPath))) {
if (localPath && (await getInfoAsync(localPath)).exists) {
validSheet.push(musicItem);
}
}
Expand Down Expand Up @@ -118,36 +119,42 @@ function parseFilename(fn: string): Partial<IMusic.IMusicItem> | null {
};
}

function localMediaFilter(_: FileStat) {
return supportLocalMediaType.some(ext => _.filename.endsWith(ext));
function localMediaFilter(filename: string) {
return supportLocalMediaType.some(ext => filename.endsWith(ext));
}

let importToken: string | null = null;
// 获取本地的文件列表
async function getMusicStats(folderPaths: string[]) {
const _importToken = nanoid();
importToken = _importToken;
const musicList: FileStat[] = [];
const musicList: string[] = [];
let peek: string | undefined;
let dirFiles: FileStat[] = [];
let dirFiles: string[] = [];
while (folderPaths.length !== 0) {
if (importToken !== _importToken) {
throw new Error('Import Broken');
}
peek = folderPaths.shift() as string;
try {
dirFiles = await FileSystem.statDir(peek);
dirFiles = await readDirectoryAsync(peek);
} catch {
dirFiles = [];
}

dirFiles.forEach(item => {
if (item.type === 'directory' && !folderPaths.includes(item.path)) {
folderPaths.push(item.path);
} else if (localMediaFilter(item)) {
musicList.push(item);
}
});
await Promise.all(
dirFiles.map(async fileName => {
const stat = await getInfoAsync(peek + '/' + fileName);
if (!stat.exists) {
return;
}
if (stat.isDirectory && !folderPaths.includes(stat.uri)) {
folderPaths.push(stat.uri);
} else if (localMediaFilter(stat.uri)) {
musicList.push(stat.uri);
}
}),
);
}
return {musicList, token: _importToken};
}
Expand All @@ -159,8 +166,9 @@ function cancelImportLocal() {
// 导入本地音乐
const groupNum = 25;
async function importLocal(_folderPaths: string[]) {
const folderPaths = [..._folderPaths];
const folderPaths = [..._folderPaths.map(it => addFileScheme(it))];
const {musicList, token} = await getMusicStats(folderPaths);
console.log('HI!!!', musicList, folderPaths, _folderPaths);
if (token !== importToken) {
throw new Error('Import Broken');
}
Expand All @@ -170,36 +178,37 @@ async function importLocal(_folderPaths: string[]) {
for (let i = 0; i < groups; ++i) {
metas = metas.concat(
await mp3Util.getMediaMeta(
musicList
.slice(i * groupNum, (i + 1) * groupNum)
.map(_ => _.path),
musicList.slice(i * groupNum, (i + 1) * groupNum),
),
);
}
if (token !== importToken) {
throw new Error('Import Broken');
}
const musicItems = await Promise.all(
musicList.map(async (musicStat, index) => {
const musicItems: IMusic.IMusicItem[] = await Promise.all(
musicList.map(async (musicPath, index) => {
let {platform, id, title, artist} =
parseFilename(musicStat.filename) ?? {};
parseFilename(getFileName(musicPath, true)) ?? {};
const meta = metas[index];
if (!platform || !id) {
platform = '本地';
id = await FileSystem.hash(musicStat.path, 'MD5');
const fileInfo = await getInfoAsync(musicPath, {
md5: true,
});
id = fileInfo.exists ? fileInfo.md5 : nanoid();
}
return {
id,
platform,
title: title ?? meta?.title ?? musicStat.filename,
title: title ?? meta?.title ?? getFileName(musicPath),
artist: artist ?? meta?.artist ?? '未知歌手',
duration: parseInt(meta?.duration ?? '0') / 1000,
duration: parseInt(meta?.duration ?? '0', 10) / 1000,
album: meta?.album ?? '未知专辑',
artwork: '',
[internalSerializeKey]: {
localPath: musicStat.path,
localPath: musicPath,
},
};
} as IMusic.IMusicItem;
}),
);
if (token !== importToken) {
Expand Down
20 changes: 12 additions & 8 deletions src/core/pluginManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import CookieManager from '@react-native-cookies/cookies';
import he from 'he';
import Network from './network';
import LocalMusicSheet from './localMusicSheet';
import {FileSystem} from 'react-native-file-access';
import {getInfoAsync} from 'expo-file-system';
import Mp3Util from '@/native/mp3Util';
import {PluginMeta} from './pluginMeta';
import {useEffect, useState} from 'react';
Expand Down Expand Up @@ -308,11 +308,7 @@ class PluginMethods implements IPlugin.IPluginInstanceMethods {
LocalMusicSheet.isLocalMusic(musicItem),
InternalDataType.LOCALPATH,
);
if (
localPath &&
(localPath.startsWith('content://') ||
(await FileSystem.exists(localPath)))
) {
if (localPath && (await getInfoAsync(localPath)).exists) {
trace('本地播放', localPath);
if (mediaExtra && mediaExtra.localPath !== localPath) {
// 修正一下本地数据
Expand Down Expand Up @@ -935,13 +931,21 @@ const localFilePlugin = new Plugin(function () {
try {
meta = await Mp3Util.getBasicMeta(urlLike);
} catch {}
const id = await FileSystem.hash(urlLike, 'MD5');
const stat = await getInfoAsync(urlLike, {
md5: true,
});
let id: string;
if (stat.exists) {
id = stat.md5 || nanoid();
} else {
id = nanoid();
}
return {
id: id,
platform: '本地',
title: meta?.title ?? getFileName(urlLike),
artist: meta?.artist ?? '未知歌手',
duration: parseInt(meta?.duration ?? '0') / 1000,
duration: parseInt(meta?.duration ?? '0', 10) / 1000,
album: meta?.album ?? '未知专辑',
artwork: '',
[internalSerializeKey]: {
Expand Down
2 changes: 2 additions & 0 deletions src/pages/fileSelector/fileItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import useTextColor from '@/hooks/useTextColor';
import Checkbox from '@/components/base/checkbox';
import {TouchableOpacity} from 'react-native-gesture-handler';
import Icon from '@/components/base/icon.tsx';
import {iconSizeConst} from '@/constants/uiConst.ts';

const ITEM_HEIGHT = rpx(96);

Expand Down Expand Up @@ -46,6 +47,7 @@ function FileItem(props: IProps) {
}
color={textColor}
style={styles.folderIcon}
size={iconSizeConst.light}
/>
<ThemeText
style={styles.path}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/fileUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export function getFileName(filePath: string, withoutExt?: boolean) {
if (lastSlash === -1) {
return filePath;
}
const fileName = filePath.slice(lastSlash);
const fileName = filePath.slice(lastSlash + 1);
if (withoutExt) {
const lastDot = fileName.lastIndexOf('.');
return lastDot === -1 ? fileName : fileName.slice(0, lastDot);
Expand Down
7 changes: 1 addition & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5316,7 +5316,7 @@ expo-constants@~16.0.0:
"@expo/config" "~9.0.0"
"@expo/env" "~0.3.0"

expo-file-system@~17.0.1:
expo-file-system@^17.0.1, expo-file-system@~17.0.1:
version "17.0.1"
resolved "https://registry.npmmirror.com/expo-file-system/-/expo-file-system-17.0.1.tgz#b9f8af8c1c06ec71d96fd7a0d2567fa9e1c88f15"
integrity sha512-dYpnZJqTGj6HCYJyXAgpFkQWsiCH3HY1ek2cFZVHFoEc5tLz9gmdEgTF6nFHurvmvfmXqxi7a5CXyVm0aFYJBw==
Expand Down Expand Up @@ -8948,11 +8948,6 @@ react-native-fast-image@^8.6.3:
resolved "https://registry.npmmirror.com/react-native-fast-image/-/react-native-fast-image-8.6.3.tgz#6edc3f9190092a909d636d93eecbcc54a8822255"
integrity sha512-Sdw4ESidXCXOmQ9EcYguNY2swyoWmx53kym2zRsvi+VeFCHEdkO+WG1DK+6W81juot40bbfLNhkc63QnWtesNg==

react-native-file-access@^3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/react-native-file-access/-/react-native-file-access-3.1.0.tgz#0e7371bc82a0899e6ad99560a5503c35801dcf4c"
integrity sha512-wOpfKpJ8s4Csfjcvf7H4L1EtmejM07HQpndzMRWAianLC50EsPc78iV8TQaw5yI7j18rh9fWMqpevz8f5a1rsA==

react-native-fs@^2.20.0:
version "2.20.0"
resolved "https://registry.npmmirror.com/react-native-fs/-/react-native-fs-2.20.0.tgz#05a9362b473bfc0910772c0acbb73a78dbc810f6"
Expand Down

0 comments on commit 5353b47

Please sign in to comment.