1cfa0fc07S猫头猫import pathConst from '@/constants/pathConst'; 2cfa0fc07S猫头猫import FastImage from 'react-native-fast-image'; 3740e3947S猫头猫import RNFS, { 4cfa0fc07S猫头猫 copyFile, 5cfa0fc07S猫头猫 downloadFile, 6cfa0fc07S猫头猫 exists, 7cfa0fc07S猫头猫 mkdir, 8cfa0fc07S猫头猫 PicturesDirectoryPath, 9cfa0fc07S猫头猫 readDir, 10cfa0fc07S猫头猫 unlink, 11cfa0fc07S猫头猫 writeFile, 12cfa0fc07S猫头猫} from 'react-native-fs'; 13b882a19dS猫头猫import {errorLog} from './log'; 14483fe585S猫头猫import path from 'path-browserify'; 15d1f226e6S猫头猫 160c266394S猫头猫export const galleryBasePath = `${PicturesDirectoryPath}/MusicFree/`; 170c266394S猫头猫 18d1f226e6S猫头猫export async function saveToGallery(src: string) { 190c266394S猫头猫 const fileName = `${galleryBasePath}${Date.now()}.png`; 200c266394S猫头猫 if (!(await exists(galleryBasePath))) { 210c266394S猫头猫 await mkdir(galleryBasePath); 22d1f226e6S猫头猫 } 23cfa0fc07S猫头猫 if (await exists(src)) { 24d1f226e6S猫头猫 try { 25cfa0fc07S猫头猫 await copyFile(src, fileName); 26d1f226e6S猫头猫 } catch (e) { 27d1f226e6S猫头猫 console.log('... ', e); 28d1f226e6S猫头猫 } 29d1f226e6S猫头猫 } 30d1f226e6S猫头猫 if (src.startsWith('http')) { 31cfa0fc07S猫头猫 await downloadFile({ 32d1f226e6S猫头猫 fromUrl: src, 33d1f226e6S猫头猫 toFile: fileName, 34d1f226e6S猫头猫 background: true, 35d1f226e6S猫头猫 }); 36d1f226e6S猫头猫 } 37d1f226e6S猫头猫 if (src.startsWith('data')) { 38cfa0fc07S猫头猫 await writeFile(fileName, src); 39d1f226e6S猫头猫 } 40d1f226e6S猫头猫} 41ff8df87dS猫头猫 42cafdf1d5S猫头猫export function sizeFormatter(bytes: number | string) { 43cafdf1d5S猫头猫 if (typeof bytes === 'string') { 44cafdf1d5S猫头猫 return bytes; 45cafdf1d5S猫头猫 } 465589cdf3S猫头猫 if (bytes === 0) { 475589cdf3S猫头猫 return '0B'; 485589cdf3S猫头猫 } 49ff8df87dS猫头猫 let k = 1024, 50ff8df87dS猫头猫 sizes = ['B', 'KB', 'MB', 'GB'], 51ff8df87dS猫头猫 i = Math.floor(Math.log(bytes) / Math.log(k)); 52ff8df87dS猫头猫 return (bytes / Math.pow(k, i)).toFixed(1) + sizes[i]; 53ff8df87dS猫头猫} 54be0a3650S猫头猫 55bae3deccS猫头猫export async function checkAndCreateDir(dirPath: string) { 56bae3deccS猫头猫 const filePath = dirPath; 57b882a19dS猫头猫 try { 58be0a3650S猫头猫 if (!(await exists(filePath))) { 59be0a3650S猫头猫 await mkdir(filePath); 60be0a3650S猫头猫 } 61b882a19dS猫头猫 } catch (e) { 62bae3deccS猫头猫 errorLog('无法初始化目录', {path: dirPath, e}); 63b882a19dS猫头猫 } 64be0a3650S猫头猫} 65cfa0fc07S猫头猫 66bae3deccS猫头猫async function getFolderSize(dirPath: string): Promise<number> { 67cfa0fc07S猫头猫 let size = 0; 68cfa0fc07S猫头猫 try { 69bae3deccS猫头猫 const fns = await readDir(dirPath); 70cfa0fc07S猫头猫 for (let fn of fns) { 71cfa0fc07S猫头猫 if (fn.isFile()) { 72cfa0fc07S猫头猫 size += fn.size; 73cfa0fc07S猫头猫 } 74cfa0fc07S猫头猫 // todo: 可以改成并行 promise.all 75cfa0fc07S猫头猫 if (fn.isDirectory()) { 76cfa0fc07S猫头猫 size += await getFolderSize(fn.path); 77cfa0fc07S猫头猫 } 78cfa0fc07S猫头猫 } 79cfa0fc07S猫头猫 } catch {} 80cfa0fc07S猫头猫 return size; 81cfa0fc07S猫头猫} 82cfa0fc07S猫头猫 83cfa0fc07S猫头猫export async function getCacheSize( 84cfa0fc07S猫头猫 type: 'music' | 'lyric' | 'image', 85cfa0fc07S猫头猫): Promise<number> { 86cfa0fc07S猫头猫 if (type === 'music') { 87cfa0fc07S猫头猫 return getFolderSize(pathConst.musicCachePath); 88cfa0fc07S猫头猫 } else if (type === 'lyric') { 89cfa0fc07S猫头猫 return getFolderSize(pathConst.lrcCachePath); 90cfa0fc07S猫头猫 } else if (type === 'image') { 91cfa0fc07S猫头猫 return getFolderSize(pathConst.imageCachePath); 92cfa0fc07S猫头猫 } 93cfa0fc07S猫头猫 throw new Error(); 94cfa0fc07S猫头猫} 95cfa0fc07S猫头猫 96cfa0fc07S猫头猫export async function clearCache(type: 'music' | 'lyric' | 'image') { 97cfa0fc07S猫头猫 if (type === 'music') { 98cfa0fc07S猫头猫 try { 99cfa0fc07S猫头猫 if (await exists(pathConst.musicCachePath)) { 100cfa0fc07S猫头猫 return unlink(pathConst.musicCachePath); 101cfa0fc07S猫头猫 } 102cfa0fc07S猫头猫 } catch {} 103cfa0fc07S猫头猫 } else if (type === 'lyric') { 104cfa0fc07S猫头猫 try { 105cfa0fc07S猫头猫 const lrcs = readDir(pathConst.lrcCachePath); 106cfa0fc07S猫头猫 return Promise.all((await lrcs).map(_ => unlink(_.path))); 107cfa0fc07S猫头猫 } catch {} 108cfa0fc07S猫头猫 } else if (type === 'image') { 109cfa0fc07S猫头猫 return FastImage.clearDiskCache(); 110cfa0fc07S猫头猫 } 111cfa0fc07S猫头猫} 1126141fdfbS猫头猫 1136141fdfbS猫头猫export function addFileScheme(fileName: string) { 1146141fdfbS猫头猫 if (fileName.startsWith('/')) { 1156141fdfbS猫头猫 return `file://${fileName}`; 1166141fdfbS猫头猫 } 1176141fdfbS猫头猫 return fileName; 1186141fdfbS猫头猫} 11929fe487bS猫头猫 12029fe487bS猫头猫export function addRandomHash(url: string) { 12129fe487bS猫头猫 if (url.indexOf('#') === -1) { 12229fe487bS猫头猫 return `${url}#${Date.now()}`; 12329fe487bS猫头猫 } 12429fe487bS猫头猫 return url; 12529fe487bS猫头猫} 12629fe487bS猫头猫 12729fe487bS猫头猫export function trimHash(url: string) { 12829fe487bS猫头猫 const index = url.lastIndexOf('#'); 12929fe487bS猫头猫 if (index === -1) { 13029fe487bS猫头猫 return url; 13129fe487bS猫头猫 } 13229fe487bS猫头猫 return url.substring(0, index); 13329fe487bS猫头猫} 134f55de8c2S猫头猫 135fd2b24adS猫头猫export function escapeCharacter(str?: string) { 1365589cdf3S猫头猫 return str !== undefined ? `${str}`.replace(/[/|\\?*"<>:]+/g, '_') : ''; 137f55de8c2S猫头猫} 138ab55f125S猫头猫 139bae3deccS猫头猫export function getDirectory(dirPath: string) { 140bae3deccS猫头猫 const lastSlash = dirPath.lastIndexOf('/'); 141ab55f125S猫头猫 if (lastSlash === -1) { 142bae3deccS猫头猫 return dirPath; 143ab55f125S猫头猫 } 144bae3deccS猫头猫 return dirPath.slice(0, lastSlash); 145ab55f125S猫头猫} 146483fe585S猫头猫 147bae3deccS猫头猫export function getFileName(filePath: string, withoutExt?: boolean) { 148bae3deccS猫头猫 const lastSlash = filePath.lastIndexOf('/'); 149a84a85c5S猫头猫 if (lastSlash === -1) { 150bae3deccS猫头猫 return filePath; 151a84a85c5S猫头猫 } 152*e593fd4aS猫头猫 let fileName = filePath.slice(lastSlash + 1); 153a84a85c5S猫头猫 if (withoutExt) { 154a84a85c5S猫头猫 const lastDot = fileName.lastIndexOf('.'); 155*e593fd4aS猫头猫 fileName = lastDot === -1 ? fileName : fileName.slice(0, lastDot); 156*e593fd4aS猫头猫 } 157*e593fd4aS猫头猫 158*e593fd4aS猫头猫 try { 159*e593fd4aS猫头猫 return decodeURIComponent(fileName); 160*e593fd4aS猫头猫 } catch { 161a84a85c5S猫头猫 return fileName; 162a84a85c5S猫头猫 } 163a84a85c5S猫头猫} 164a84a85c5S猫头猫 165483fe585S猫头猫export async function mkdirR(directory: string) { 166483fe585S猫头猫 let folder = directory; 1675589cdf3S猫头猫 const checkStack: string[] = []; 168483fe585S猫头猫 while (folder.length > 15) { 169483fe585S猫头猫 checkStack.push(folder); 170483fe585S猫头猫 folder = path.dirname(folder); 171483fe585S猫头猫 } 172483fe585S猫头猫 let existPos = 0; 173483fe585S猫头猫 for (let i = 0; i < checkStack.length; ++i) { 174483fe585S猫头猫 const isExist = await exists(checkStack[i]); 175483fe585S猫头猫 if (isExist) { 176483fe585S猫头猫 existPos = i; 177483fe585S猫头猫 break; 178483fe585S猫头猫 } 179483fe585S猫头猫 } 180483fe585S猫头猫 181483fe585S猫头猫 for (let j = existPos - 1; j >= 0; --j) { 182483fe585S猫头猫 try { 183483fe585S猫头猫 await mkdir(checkStack[j]); 184483fe585S猫头猫 } catch (e) { 185483fe585S猫头猫 console.log('error', e); 186483fe585S猫头猫 } 187483fe585S猫头猫 } 188483fe585S猫头猫} 189740e3947S猫头猫 190740e3947S猫头猫export async function writeInChunks( 191740e3947S猫头猫 filePath: string, 192740e3947S猫头猫 data, 193740e3947S猫头猫 chunkSize = 1024 * 1024 * 2, 194740e3947S猫头猫) { 195740e3947S猫头猫 let offset = 0; 196740e3947S猫头猫 console.log('here'); 197740e3947S猫头猫 if (await exists(filePath)) { 198740e3947S猫头猫 await unlink(filePath); 199740e3947S猫头猫 } 200740e3947S猫头猫 201740e3947S猫头猫 while (offset < data.length) { 202740e3947S猫头猫 const chunk = data.slice(offset, offset + chunkSize); 203740e3947S猫头猫 if (offset === 0) { 204740e3947S猫头猫 await RNFS.writeFile(filePath, chunk, 'utf8'); 205740e3947S猫头猫 } else { 206740e3947S猫头猫 await RNFS.appendFile(filePath, chunk, 'utf8'); 207740e3947S猫头猫 } 208740e3947S猫头猫 offset += chunkSize; 209740e3947S猫头猫 } 210740e3947S猫头猫} 211