import pathConst from "@/constants/pathConst";
import FastImage from "react-native-fast-image";
import RNFS, {
PicturesDirectoryPath,
copyFile,
downloadFile,
exists,
mkdir,
readDir,
unlink,
writeFile,
} from "react-native-fs";
import { errorLog } from "./log";
import path from "path-browserify";
import resolveAssetSource from "react-native/Libraries/Image/resolveAssetSource";
const galleryBasePath = `${PicturesDirectoryPath}/MusicFree/`;
* 将图片保存到相册
* @param src 图片地址
* @returns 保存后的文件路径
*/
export async function saveToGallery(src: string) {
const fileName = `${galleryBasePath}${Date.now()}.png`;
if (!(await exists(galleryBasePath))) {
await mkdir(galleryBasePath);
}
if (await exists(src)) {
try {
await copyFile(src, fileName);
} catch (e) {
console.log("... ", e);
}
}
if (src.startsWith("http")) {
const { promise } = downloadFile({
fromUrl: src,
toFile: fileName,
background: true,
});
await promise;
}
if (src.startsWith("data")) {
await writeFile(fileName, src);
}
return fileName;
}
export function sizeFormatter(bytes: number | string) {
if (typeof bytes === "string") {
return bytes;
}
if (bytes === 0) {
return "0B";
}
let k = 1024,
sizes = ["B", "KB", "MB", "GB"],
i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toFixed(1) + sizes[i];
}
export async function checkAndCreateDir(dirPath: string) {
const filePath = dirPath;
try {
if (!(await exists(filePath))) {
await mkdir(filePath);
}
} catch (e) {
errorLog("无法初始化目录", { path: dirPath, e });
}
}
async function getFolderSize(dirPath: string): Promise<number> {
let size = 0;
try {
const fns = await readDir(dirPath);
for (let fn of fns) {
if (fn.isFile()) {
size += fn.size;
}
if (fn.isDirectory()) {
size += await getFolderSize(fn.path);
}
}
} catch {}
return size;
}
export async function getCacheSize(
type: "music" | "lyric" | "image",
): Promise<number> {
if (type === "music") {
return getFolderSize(pathConst.musicCachePath);
} else if (type === "lyric") {
return getFolderSize(pathConst.lrcCachePath);
} else if (type === "image") {
return getFolderSize(pathConst.imageCachePath);
}
throw new Error();
}
export async function clearCache(type: "music" | "lyric" | "image") {
if (type === "music") {
try {
if (await exists(pathConst.musicCachePath)) {
return unlink(pathConst.musicCachePath);
}
} catch {}
} else if (type === "lyric") {
try {
const lrcs = readDir(pathConst.lrcCachePath);
return Promise.all((await lrcs).map(_ => unlink(_.path)));
} catch {}
} else if (type === "image") {
return FastImage.clearDiskCache();
}
}
export function addFileScheme(fileName: string) {
if (fileName.startsWith("/")) {
return `file://${fileName}`;
}
return fileName;
}
export function addRandomHash(url: string) {
if (url.indexOf("#") === -1) {
return `${url}#${Date.now()}`;
}
return url;
}
export function trimHash(url: string) {
const index = url.lastIndexOf("#");
if (index === -1) {
return url;
}
return url.substring(0, index);
}
export function escapeCharacter(str?: string) {
return str !== undefined ? `${str}`.replace(/[/|\\?*"<>:]+/g, "_") : "";
}
export function getDirectory(dirPath: string) {
const lastSlash = dirPath.lastIndexOf("/");
if (lastSlash === -1) {
return dirPath;
}
return dirPath.slice(0, lastSlash);
}
export function getFileName(filePath: string, withoutExt?: boolean) {
const lastSlash = filePath.lastIndexOf("/");
if (lastSlash === -1) {
return filePath;
}
let fileName = filePath.slice(lastSlash + 1);
if (withoutExt) {
const lastDot = fileName.lastIndexOf(".");
fileName = lastDot === -1 ? fileName : fileName.slice(0, lastDot);
}
try {
return decodeURIComponent(fileName);
} catch {
return fileName;
}
}
export async function mkdirR(directory: string) {
let folder = directory;
const checkStack: string[] = [];
while (folder.length > 15) {
checkStack.push(folder);
folder = path.dirname(folder);
}
let existPos = 0;
for (let i = 0; i < checkStack.length; ++i) {
const isExist = await exists(checkStack[i]);
if (isExist) {
existPos = i;
break;
}
}
for (let j = existPos - 1; j >= 0; --j) {
try {
await mkdir(checkStack[j]);
} catch (e) {
console.log("error", e);
}
}
}
export async function writeInChunks(
filePath: string,
data,
chunkSize = 1024 * 1024 * 2,
) {
let offset = 0;
if (await exists(filePath)) {
await unlink(filePath);
}
while (offset < data.length) {
const chunk = data.slice(offset, offset + chunkSize);
if (offset === 0) {
await RNFS.writeFile(filePath, chunk, "utf8");
} else {
await RNFS.appendFile(filePath, chunk, "utf8");
}
offset += chunkSize;
}
}
export function resolveImportedAssetOrPath(pathOrAsset: string | number | undefined) {
return pathOrAsset === undefined
? undefined
: typeof pathOrAsset === "string"
? pathOrAsset
: resolveImportedAsset(pathOrAsset);
}
function resolveImportedAsset(id?: number) {
return id
? (resolveAssetSource(id) as { uri: string } | null) ?? undefined
: undefined;
}