1bf6e62f2S猫头猫import {check, PERMISSIONS, request} from 'react-native-permissions'; 25500cea7S猫头猫import RNTrackPlayer, { 35500cea7S猫头猫 AppKilledPlaybackBehavior, 45500cea7S猫头猫 Capability, 55500cea7S猫头猫} from 'react-native-track-player'; 6bf6e62f2S猫头猫import 'react-native-get-random-values'; 7e22d5e4fS猫头猫import Config from '@/core/config'; 86780f402S猫头猫import pathConst from '@/constants/pathConst'; 9be0a3650S猫头猫import {checkAndCreateDir} from '@/utils/fileUtils'; 101e263108S猫头猫import {errorLog, trace} from '@/utils/log'; 1143eb30bfS猫头猫import MediaMeta from '@/core/mediaMeta.old'; 12927dbe93S猫头猫import PluginManager from '@/core/pluginManager'; 13ef714860S猫头猫import Network from '@/core/network'; 14c30d30e1S猫头猫import {ImgAsset} from '@/constants/assetsConst'; 150e4173cdS猫头猫import LocalMusicSheet from '@/core/localMusicSheet'; 16740e3947S猫头猫import {Linking, Platform} from 'react-native'; 17a27adc20S猫头猫import Theme from '@/core/theme'; 1857277364S猫头猫import LyricManager from '@/core/lyricManager'; 19a84a85c5S猫头猫import Toast from '@/utils/toast'; 20a84a85c5S猫头猫import {localPluginHash, supportLocalMediaType} from '@/constants/commonConst'; 215500cea7S猫头猫import TrackPlayer from '@/core/trackPlayer'; 225500cea7S猫头猫import musicHistory from '@/core/musicHistory'; 230dd58d38S猫头猫import PersistStatus from '@/core/persistStatus'; 2491eb8fa8S猫头猫import {perfLogger} from '@/utils/perfLogger'; 255589cdf3S猫头猫import * as SplashScreen from 'expo-splash-screen'; 26740e3947S猫头猫import MusicSheet from '@/core/musicSheet'; 27740e3947S猫头猫import NativeUtils from '@/native/utils'; 28740e3947S猫头猫import {showDialog} from '@/components/dialogs/useDialog.ts'; 29bf6e62f2S猫头猫 308b88e961S猫头猫/** app加载前执行 318b88e961S猫头猫 * 1. 检查权限 328b88e961S猫头猫 * 2. 数据初始化 338b88e961S猫头猫 * 3. 348b88e961S猫头猫 */ 3591eb8fa8S猫头猫 3694a1b1fcS猫头猫async function _bootstrap() { 375589cdf3S猫头猫 await SplashScreen.preventAutoHideAsync() 385589cdf3S猫头猫 .then(result => 395589cdf3S猫头猫 console.log( 405589cdf3S猫头猫 `SplashScreen.preventAutoHideAsync() succeeded: ${result}`, 415589cdf3S猫头猫 ), 425589cdf3S猫头猫 ) 435589cdf3S猫头猫 .catch(console.warn); // it's good to explicitly catch and inspect any error 4491eb8fa8S猫头猫 const logger = perfLogger(); 45927dbe93S猫头猫 // 1. 检查权限 46740e3947S猫头猫 if (Platform.OS === 'android' && Platform.Version >= 30) { 47740e3947S猫头猫 const hasPermission = await NativeUtils.checkStoragePermission(); 48740e3947S猫头猫 if ( 49740e3947S猫头猫 !hasPermission && 50740e3947S猫头猫 !PersistStatus.get('app.skipBootstrapStorageDialog') 51740e3947S猫头猫 ) { 52740e3947S猫头猫 showDialog('CheckStorage'); 53740e3947S猫头猫 } 54740e3947S猫头猫 } else { 55740e3947S猫头猫 const [readStoragePermission, writeStoragePermission] = 56740e3947S猫头猫 await Promise.all([ 57bf6e62f2S猫头猫 check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE), 58bf6e62f2S猫头猫 check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE), 59bf6e62f2S猫头猫 ]); 60bf6e62f2S猫头猫 if ( 61bf6e62f2S猫头猫 !( 62bf6e62f2S猫头猫 readStoragePermission === 'granted' && 63bf6e62f2S猫头猫 writeStoragePermission === 'granted' 64bf6e62f2S猫头猫 ) 65bf6e62f2S猫头猫 ) { 66bf6e62f2S猫头猫 await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE); 67bf6e62f2S猫头猫 await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE); 68bf6e62f2S猫头猫 } 69740e3947S猫头猫 } 7091eb8fa8S猫头猫 logger.mark('权限检查完成'); 71bf6e62f2S猫头猫 72927dbe93S猫头猫 // 2. 数据初始化 736780f402S猫头猫 /** 初始化路径 */ 746780f402S猫头猫 await setupFolder(); 751e263108S猫头猫 trace('文件夹初始化完成'); 7691eb8fa8S猫头猫 logger.mark('文件夹初始化完成'); 7791eb8fa8S猫头猫 78bf6e62f2S猫头猫 // 加载配置 79ef714860S猫头猫 await Promise.all([ 8091eb8fa8S猫头猫 Config.setup().then(() => { 8191eb8fa8S猫头猫 logger.mark('Config'); 8291eb8fa8S猫头猫 }), 8391eb8fa8S猫头猫 MediaMeta.setup().then(() => { 8491eb8fa8S猫头猫 logger.mark('MediaMeta'); 8591eb8fa8S猫头猫 }), 8691eb8fa8S猫头猫 MusicSheet.setup().then(() => { 8791eb8fa8S猫头猫 logger.mark('MusicSheet'); 8891eb8fa8S猫头猫 }), 8991eb8fa8S猫头猫 musicHistory.setupMusicHistory().then(() => { 9091eb8fa8S猫头猫 logger.mark('musicHistory'); 9191eb8fa8S猫头猫 }), 92ef714860S猫头猫 ]); 931e263108S猫头猫 trace('配置初始化完成'); 9491eb8fa8S猫头猫 logger.mark('配置初始化完成'); 9591eb8fa8S猫头猫 96bf6e62f2S猫头猫 // 加载插件 9794a1b1fcS猫头猫 try { 985500cea7S猫头猫 await RNTrackPlayer.setupPlayer({ 99b882a19dS猫头猫 maxCacheSize: 100b882a19dS猫头猫 Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512, 101cfa0fc07S猫头猫 }); 10294a1b1fcS猫头猫 } catch (e: any) { 10394a1b1fcS猫头猫 if ( 1044060c00aS猫头猫 e?.message !== 1054060c00aS猫头猫 'The player has already been initialized via setupPlayer.' 10694a1b1fcS猫头猫 ) { 10794a1b1fcS猫头猫 throw e; 10894a1b1fcS猫头猫 } 10994a1b1fcS猫头猫 } 11091eb8fa8S猫头猫 logger.mark('加载播放器'); 11166e1d5fcS猫头猫 11266e1d5fcS猫头猫 const capabilities = Config.get('setting.basic.showExitOnNotification') 11366e1d5fcS猫头猫 ? [ 11466e1d5fcS猫头猫 Capability.Play, 11566e1d5fcS猫头猫 Capability.Pause, 11666e1d5fcS猫头猫 Capability.SkipToNext, 11766e1d5fcS猫头猫 Capability.SkipToPrevious, 11866e1d5fcS猫头猫 Capability.Stop, 11966e1d5fcS猫头猫 ] 12066e1d5fcS猫头猫 : [ 12166e1d5fcS猫头猫 Capability.Play, 12266e1d5fcS猫头猫 Capability.Pause, 12366e1d5fcS猫头猫 Capability.SkipToNext, 12466e1d5fcS猫头猫 Capability.SkipToPrevious, 12566e1d5fcS猫头猫 ]; 1265500cea7S猫头猫 await RNTrackPlayer.updateOptions({ 1272aa88193S猫头猫 icon: ImgAsset.logoTransparent, 128e2257bd6S猫头猫 progressUpdateEventInterval: 1, 1295500cea7S猫头猫 android: { 1305500cea7S猫头猫 alwaysPauseOnInterruption: true, 1315500cea7S猫头猫 appKilledPlaybackBehavior: 1325500cea7S猫头猫 AppKilledPlaybackBehavior.ContinuePlayback, 1335500cea7S猫头猫 }, 13466e1d5fcS猫头猫 capabilities: capabilities, 13566e1d5fcS猫头猫 compactCapabilities: capabilities, 13666e1d5fcS猫头猫 notificationCapabilities: [...capabilities, Capability.SeekTo], 1370d39db21S猫头猫 }); 13891eb8fa8S猫头猫 logger.mark('播放器初始化完成'); 1391e263108S猫头猫 trace('播放器初始化完成'); 14091eb8fa8S猫头猫 1418b88e961S猫头猫 await PluginManager.setup(); 14291eb8fa8S猫头猫 logger.mark('插件初始化完成'); 14391eb8fa8S猫头猫 1441e263108S猫头猫 trace('插件初始化完成'); 1455500cea7S猫头猫 await TrackPlayer.setupTrackPlayer(); 1461e263108S猫头猫 trace('播放列表初始化完成'); 14791eb8fa8S猫头猫 logger.mark('播放列表初始化完成'); 14891eb8fa8S猫头猫 1490e4173cdS猫头猫 await LocalMusicSheet.setup(); 1500e4173cdS猫头猫 trace('本地音乐初始化完成'); 15191eb8fa8S猫头猫 logger.mark('本地音乐初始化完成'); 15291eb8fa8S猫头猫 153a27adc20S猫头猫 Theme.setup(); 154a27adc20S猫头猫 trace('主题初始化完成'); 15591eb8fa8S猫头猫 logger.mark('主题初始化完成'); 15691eb8fa8S猫头猫 15757277364S猫头猫 await LyricManager.setup(); 1588b88e961S猫头猫 15991eb8fa8S猫头猫 logger.mark('歌词初始化完成'); 16091eb8fa8S猫头猫 161b3a3a048S猫头猫 extraMakeup(); 162c79c8a57S猫头猫 ErrorUtils.setGlobalHandler(error => { 163c79c8a57S猫头猫 errorLog('未捕获的错误', error); 164c79c8a57S猫头猫 }); 165bf6e62f2S猫头猫} 1666c6f45bdS猫头猫 1676c6f45bdS猫头猫/** 初始化 */ 1686c6f45bdS猫头猫async function setupFolder() { 1696780f402S猫头猫 await Promise.all([ 170be0a3650S猫头猫 checkAndCreateDir(pathConst.dataPath), 1717f771613S猫头猫 checkAndCreateDir(pathConst.logPath), 1727f771613S猫头猫 checkAndCreateDir(pathConst.cachePath), 173c79c8a57S猫头猫 checkAndCreateDir(pathConst.pluginPath), 17494a1b1fcS猫头猫 checkAndCreateDir(pathConst.lrcCachePath), 175*42a9f3e6Smaotoumao checkAndCreateDir(pathConst.downloadCachePath), 17626f32636S猫头猫 checkAndCreateDir(pathConst.localLrcPath), 1770e4173cdS猫头猫 checkAndCreateDir(pathConst.downloadPath).then(() => { 1780e4173cdS猫头猫 checkAndCreateDir(pathConst.downloadMusicPath); 1790e4173cdS猫头猫 }), 1806780f402S猫头猫 ]); 1816c6f45bdS猫头猫} 18294a1b1fcS猫头猫 18394a1b1fcS猫头猫export default async function () { 18494a1b1fcS猫头猫 try { 18594a1b1fcS猫头猫 await _bootstrap(); 18694a1b1fcS猫头猫 } catch (e) { 18794a1b1fcS猫头猫 errorLog('初始化出错', e); 18894a1b1fcS猫头猫 } 18994a1b1fcS猫头猫 // 隐藏开屏动画 19094a1b1fcS猫头猫 console.log('HIDE'); 1915589cdf3S猫头猫 await SplashScreen.hideAsync(); 19294a1b1fcS猫头猫} 193b3a3a048S猫头猫 194b3a3a048S猫头猫/** 不需要阻塞的 */ 195b3a3a048S猫头猫async function extraMakeup() { 196a84a85c5S猫头猫 // 自动更新 197b3a3a048S猫头猫 try { 19891eb8fa8S猫头猫 // 初始化网络状态 19991eb8fa8S猫头猫 Network.setup(); 20091eb8fa8S猫头猫 201b3a3a048S猫头猫 if (Config.get('setting.basic.autoUpdatePlugin')) { 2020dd58d38S猫头猫 const lastUpdated = PersistStatus.get('app.pluginUpdateTime') || 0; 203b3a3a048S猫头猫 const now = Date.now(); 204b3a3a048S猫头猫 if (Math.abs(now - lastUpdated) > 86400000) { 2050dd58d38S猫头猫 PersistStatus.set('app.pluginUpdateTime', now); 206b3a3a048S猫头猫 const plugins = PluginManager.getValidPlugins(); 207b3a3a048S猫头猫 for (let i = 0; i < plugins.length; ++i) { 208b3a3a048S猫头猫 const srcUrl = plugins[i].instance.srcUrl; 209b3a3a048S猫头猫 if (srcUrl) { 210b3a3a048S猫头猫 await PluginManager.installPluginFromUrl(srcUrl); 211b3a3a048S猫头猫 } 212b3a3a048S猫头猫 } 213b3a3a048S猫头猫 } 214b3a3a048S猫头猫 } 215b3a3a048S猫头猫 } catch {} 216a84a85c5S猫头猫 217a84a85c5S猫头猫 async function handleLinkingUrl(url: string) { 218a84a85c5S猫头猫 // 插件 219a84a85c5S猫头猫 try { 220eea2f34fS猫头猫 if (url.startsWith('musicfree://install/')) { 221eea2f34fS猫头猫 const plugins = url 222eea2f34fS猫头猫 .slice(20) 223eea2f34fS猫头猫 .split(',') 224eea2f34fS猫头猫 .map(decodeURIComponent); 225eea2f34fS猫头猫 await Promise.all( 226eea2f34fS猫头猫 plugins.map(it => 227eea2f34fS猫头猫 PluginManager.installPluginFromUrl(it).catch(() => {}), 228eea2f34fS猫头猫 ), 229eea2f34fS猫头猫 ); 230eea2f34fS猫头猫 Toast.success('安装成功~'); 231eea2f34fS猫头猫 } else if (url.endsWith('.js')) { 232e36e2599S猫头猫 PluginManager.installPlugin(url, { 233e36e2599S猫头猫 notCheckVersion: Config.get( 234e36e2599S猫头猫 'setting.basic.notCheckPluginVersion', 235e36e2599S猫头猫 ), 236e36e2599S猫头猫 }) 237a84a85c5S猫头猫 .then(res => { 238a84a85c5S猫头猫 Toast.success(`插件「${res.name}」安装成功~`); 239a84a85c5S猫头猫 }) 240a84a85c5S猫头猫 .catch(e => { 241a84a85c5S猫头猫 console.log(e); 242a84a85c5S猫头猫 Toast.warn(e?.message ?? '无法识别此插件'); 243a84a85c5S猫头猫 }); 244a84a85c5S猫头猫 } else if (supportLocalMediaType.some(it => url.endsWith(it))) { 245a84a85c5S猫头猫 // 本地播放 246a84a85c5S猫头猫 const musicItem = await PluginManager.getByHash( 247a84a85c5S猫头猫 localPluginHash, 248a84a85c5S猫头猫 )?.instance?.importMusicItem?.(url); 249a84a85c5S猫头猫 console.log(musicItem); 250a84a85c5S猫头猫 if (musicItem) { 2515500cea7S猫头猫 TrackPlayer.play(musicItem); 252a84a85c5S猫头猫 } 253a84a85c5S猫头猫 } 254a84a85c5S猫头猫 } catch {} 255a84a85c5S猫头猫 } 256a84a85c5S猫头猫 257a84a85c5S猫头猫 // 开启监听 258a84a85c5S猫头猫 Linking.addEventListener('url', data => { 259a84a85c5S猫头猫 if (data.url) { 260a84a85c5S猫头猫 handleLinkingUrl(data.url); 261a84a85c5S猫头猫 } 262a84a85c5S猫头猫 }); 263a84a85c5S猫头猫 const initUrl = await Linking.getInitialURL(); 264a84a85c5S猫头猫 if (initUrl) { 265a84a85c5S猫头猫 handleLinkingUrl(initUrl); 266a84a85c5S猫头猫 } 267aaa0db32S猫头猫 268aaa0db32S猫头猫 if (Config.get('setting.basic.autoPlayWhenAppStart')) { 2695500cea7S猫头猫 TrackPlayer.play(); 270aaa0db32S猫头猫 } 271b3a3a048S猫头猫} 272