1242960d3S猫头猫import MusicQueue from '@/core/musicQueue'; 2e14deecfS猫头猫import MusicSheet from '@/core/musicSheet'; 3bf6e62f2S猫头猫import {check, PERMISSIONS, request} from 'react-native-permissions'; 4bf6e62f2S猫头猫import TrackPlayer, {Capability} from 'react-native-track-player'; 5bf6e62f2S猫头猫import 'react-native-get-random-values'; 6e22d5e4fS猫头猫import Config from '@/core/config'; 70d39db21S猫头猫import RNBootSplash from 'react-native-bootsplash'; 86780f402S猫头猫import pathConst from '@/constants/pathConst'; 9be0a3650S猫头猫import {checkAndCreateDir} from '@/utils/fileUtils'; 101e263108S猫头猫import {errorLog, trace} from '@/utils/log'; 1128bde18bS猫头猫import MediaMeta from '@/core/mediaMeta'; 123d6d339aS猫头猫import Cache from '@/core/cache'; 13927dbe93S猫头猫import PluginManager from '@/core/pluginManager'; 14ef714860S猫头猫import Network from '@/core/network'; 15c30d30e1S猫头猫import {ImgAsset} from '@/constants/assetsConst'; 160e4173cdS猫头猫import LocalMusicSheet from '@/core/localMusicSheet'; 17*a84a85c5S猫头猫import {Linking, StatusBar} from 'react-native'; 18a27adc20S猫头猫import Theme from '@/core/theme'; 1957277364S猫头猫import LyricManager from '@/core/lyricManager'; 20b3a3a048S猫头猫import {getStorage, setStorage} from '@/utils/storage'; 21*a84a85c5S猫头猫import Toast from '@/utils/toast'; 22*a84a85c5S猫头猫import {localPluginHash, supportLocalMediaType} from '@/constants/commonConst'; 23bf6e62f2S猫头猫 248b88e961S猫头猫/** app加载前执行 258b88e961S猫头猫 * 1. 检查权限 268b88e961S猫头猫 * 2. 数据初始化 278b88e961S猫头猫 * 3. 288b88e961S猫头猫 */ 2994a1b1fcS猫头猫async function _bootstrap() { 30927dbe93S猫头猫 // 1. 检查权限 31bf6e62f2S猫头猫 const [readStoragePermission, writeStoragePermission] = await Promise.all([ 32bf6e62f2S猫头猫 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 33bf6e62f2S猫头猫 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 34bf6e62f2S猫头猫 ]); 35bf6e62f2S猫头猫 if ( 36bf6e62f2S猫头猫 !( 37bf6e62f2S猫头猫 readStoragePermission === 'granted' && 38bf6e62f2S猫头猫 writeStoragePermission === 'granted' 39bf6e62f2S猫头猫 ) 40bf6e62f2S猫头猫 ) { 41bf6e62f2S猫头猫 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 42bf6e62f2S猫头猫 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 43bf6e62f2S猫头猫 } 44bf6e62f2S猫头猫 45927dbe93S猫头猫 // 2. 数据初始化 466780f402S猫头猫 /** 初始化路径 */ 476780f402S猫头猫 await setupFolder(); 481e263108S猫头猫 trace('文件夹初始化完成'); 49bf6e62f2S猫头猫 // 加载配置 50ef714860S猫头猫 await Promise.all([ 51ef714860S猫头猫 Config.setup(), 52ef714860S猫头猫 MediaMeta.setup(), 53ef714860S猫头猫 MusicSheet.setup(), 54ef714860S猫头猫 Network.setup(), 55ef714860S猫头猫 ]); 561e263108S猫头猫 trace('配置初始化完成'); 57bf6e62f2S猫头猫 // 加载插件 5894a1b1fcS猫头猫 try { 59cfa0fc07S猫头猫 await TrackPlayer.setupPlayer({ 60b882a19dS猫头猫 maxCacheSize: 61b882a19dS猫头猫 Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512, 62cfa0fc07S猫头猫 }); 6394a1b1fcS猫头猫 } catch (e: any) { 6494a1b1fcS猫头猫 if ( 654060c00aS猫头猫 e?.message !== 664060c00aS猫头猫 'The player has already been initialized via setupPlayer.' 6794a1b1fcS猫头猫 ) { 6894a1b1fcS猫头猫 throw e; 6994a1b1fcS猫头猫 } 7094a1b1fcS猫头猫 } 71bf6e62f2S猫头猫 await TrackPlayer.updateOptions({ 722aa88193S猫头猫 icon: ImgAsset.logoTransparent, 7303051250S猫头猫 alwaysPauseOnInterruption: true, 74e2257bd6S猫头猫 progressUpdateEventInterval: 1, 75bf6e62f2S猫头猫 capabilities: [ 76bf6e62f2S猫头猫 Capability.Play, 77bf6e62f2S猫头猫 Capability.Pause, 78bf6e62f2S猫头猫 Capability.SkipToNext, 79bf6e62f2S猫头猫 Capability.SkipToPrevious, 80bf6e62f2S猫头猫 ], 81bf6e62f2S猫头猫 compactCapabilities: [ 82bf6e62f2S猫头猫 Capability.Play, 83bf6e62f2S猫头猫 Capability.Pause, 84bf6e62f2S猫头猫 Capability.SkipToNext, 85bf6e62f2S猫头猫 Capability.SkipToPrevious, 86bf6e62f2S猫头猫 ], 87bf6e62f2S猫头猫 notificationCapabilities: [ 88bf6e62f2S猫头猫 Capability.Play, 89bf6e62f2S猫头猫 Capability.Pause, 90bf6e62f2S猫头猫 Capability.SkipToNext, 91bf6e62f2S猫头猫 Capability.SkipToPrevious, 920d39db21S猫头猫 ], 930d39db21S猫头猫 }); 941e263108S猫头猫 trace('播放器初始化完成'); 954060c00aS猫头猫 await Cache.setup(); 961e263108S猫头猫 trace('缓存初始化完成'); 978b88e961S猫头猫 await PluginManager.setup(); 981e263108S猫头猫 trace('插件初始化完成'); 99927dbe93S猫头猫 await MusicQueue.setup(); 1001e263108S猫头猫 trace('播放列表初始化完成'); 1010e4173cdS猫头猫 await LocalMusicSheet.setup(); 1020e4173cdS猫头猫 trace('本地音乐初始化完成'); 103a27adc20S猫头猫 Theme.setup(); 104a27adc20S猫头猫 trace('主题初始化完成'); 10557277364S猫头猫 await LyricManager.setup(); 1068b88e961S猫头猫 10795f955b7S猫头猫 StatusBar.setBackgroundColor('transparent'); 10895f955b7S猫头猫 StatusBar.setTranslucent(true); 10995f955b7S猫头猫 110b3a3a048S猫头猫 extraMakeup(); 111c79c8a57S猫头猫 ErrorUtils.setGlobalHandler(error => { 112c79c8a57S猫头猫 errorLog('未捕获的错误', error); 113c79c8a57S猫头猫 }); 114bf6e62f2S猫头猫} 1156c6f45bdS猫头猫 1166c6f45bdS猫头猫/** 初始化 */ 1176c6f45bdS猫头猫async function setupFolder() { 1186780f402S猫头猫 await Promise.all([ 119be0a3650S猫头猫 checkAndCreateDir(pathConst.dataPath), 1207f771613S猫头猫 checkAndCreateDir(pathConst.logPath), 1217f771613S猫头猫 checkAndCreateDir(pathConst.cachePath), 122c79c8a57S猫头猫 checkAndCreateDir(pathConst.pluginPath), 12394a1b1fcS猫头猫 checkAndCreateDir(pathConst.lrcCachePath), 1240e4173cdS猫头猫 checkAndCreateDir(pathConst.downloadPath).then(() => { 1250e4173cdS猫头猫 checkAndCreateDir(pathConst.downloadMusicPath); 1260e4173cdS猫头猫 }), 1276780f402S猫头猫 ]); 1286c6f45bdS猫头猫} 12994a1b1fcS猫头猫 13094a1b1fcS猫头猫export default async function () { 13194a1b1fcS猫头猫 try { 13294a1b1fcS猫头猫 await _bootstrap(); 13394a1b1fcS猫头猫 } catch (e) { 13494a1b1fcS猫头猫 errorLog('初始化出错', e); 13594a1b1fcS猫头猫 } 13694a1b1fcS猫头猫 // 隐藏开屏动画 13794a1b1fcS猫头猫 console.log('HIDE'); 13894a1b1fcS猫头猫 RNBootSplash.hide({fade: true}); 13994a1b1fcS猫头猫} 140b3a3a048S猫头猫 141b3a3a048S猫头猫/** 不需要阻塞的 */ 142b3a3a048S猫头猫async function extraMakeup() { 143*a84a85c5S猫头猫 // 自动更新 144b3a3a048S猫头猫 try { 145b3a3a048S猫头猫 if (Config.get('setting.basic.autoUpdatePlugin')) { 146b3a3a048S猫头猫 const lastUpdated = 147b3a3a048S猫头猫 (await getStorage('pluginLastupdatedTime')) || 0; 148b3a3a048S猫头猫 const now = Date.now(); 149b3a3a048S猫头猫 if (Math.abs(now - lastUpdated) > 86400000) { 150b3a3a048S猫头猫 setStorage('pluginLastupdatedTime', now); 151b3a3a048S猫头猫 const plugins = PluginManager.getValidPlugins(); 152b3a3a048S猫头猫 for (let i = 0; i < plugins.length; ++i) { 153b3a3a048S猫头猫 const srcUrl = plugins[i].instance.srcUrl; 154b3a3a048S猫头猫 if (srcUrl) { 155b3a3a048S猫头猫 await PluginManager.installPluginFromUrl(srcUrl); 156b3a3a048S猫头猫 } 157b3a3a048S猫头猫 } 158b3a3a048S猫头猫 } 159b3a3a048S猫头猫 } 160b3a3a048S猫头猫 } catch {} 161*a84a85c5S猫头猫 162*a84a85c5S猫头猫 async function handleLinkingUrl(url: string) { 163*a84a85c5S猫头猫 // 插件 164*a84a85c5S猫头猫 try { 165*a84a85c5S猫头猫 if (url.endsWith('.js')) { 166*a84a85c5S猫头猫 PluginManager.installPlugin(url) 167*a84a85c5S猫头猫 .then(res => { 168*a84a85c5S猫头猫 Toast.success(`插件「${res.name}」安装成功~`); 169*a84a85c5S猫头猫 }) 170*a84a85c5S猫头猫 .catch(e => { 171*a84a85c5S猫头猫 console.log(e); 172*a84a85c5S猫头猫 Toast.warn(e?.message ?? '无法识别此插件'); 173*a84a85c5S猫头猫 }); 174*a84a85c5S猫头猫 } else if (supportLocalMediaType.some(it => url.endsWith(it))) { 175*a84a85c5S猫头猫 // 本地播放 176*a84a85c5S猫头猫 const musicItem = await PluginManager.getByHash( 177*a84a85c5S猫头猫 localPluginHash, 178*a84a85c5S猫头猫 )?.instance?.importMusicItem?.(url); 179*a84a85c5S猫头猫 console.log(musicItem); 180*a84a85c5S猫头猫 if (musicItem) { 181*a84a85c5S猫头猫 MusicQueue.play(musicItem); 182*a84a85c5S猫头猫 } 183*a84a85c5S猫头猫 } 184*a84a85c5S猫头猫 } catch {} 185*a84a85c5S猫头猫 } 186*a84a85c5S猫头猫 187*a84a85c5S猫头猫 // 开启监听 188*a84a85c5S猫头猫 Linking.addEventListener('url', data => { 189*a84a85c5S猫头猫 if (data.url) { 190*a84a85c5S猫头猫 handleLinkingUrl(data.url); 191*a84a85c5S猫头猫 } 192*a84a85c5S猫头猫 }); 193*a84a85c5S猫头猫 const initUrl = await Linking.getInitialURL(); 194*a84a85c5S猫头猫 if (initUrl) { 195*a84a85c5S猫头猫 handleLinkingUrl(initUrl); 196*a84a85c5S猫头猫 } 197b3a3a048S猫头猫} 198