xref: /MusicFree/src/entry/bootstrap.ts (revision 242960d3fe7b3524027774192799cef72e2b818e)
1import MusicQueue from '@/core/musicQueue';
2import MusicSheet from '@/core/musicSheetManager';
3import {check, PERMISSIONS, request} from 'react-native-permissions';
4import TrackPlayer, {Capability} from 'react-native-track-player';
5import {pluginManager} from '../core/pluginManager';
6import 'react-native-get-random-values';
7import {Platform, ToastAndroid} from 'react-native';
8import {loadConfig} from '@/core/localConfigManager';
9import RNBootSplash from 'react-native-bootsplash';
10import RNFS, {exists, mkdir} from 'react-native-fs';
11import DownloadManager from '@/core/downloadManager';
12import pathConst from '@/constants/pathConst';
13import {checkAndCreateDir} from '@/utils/fileUtils';
14import {errorLog} from '@/utils/log';
15import MediaMetaManager from '@/core/mediaMetaManager';
16
17/** app加载前执行 */
18async function _bootstrap() {
19  // 检查权限
20  const [readStoragePermission, writeStoragePermission] = await Promise.all([
21    check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE),
22    check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE),
23  ]);
24  if (
25    !(
26      readStoragePermission === 'granted' &&
27      writeStoragePermission === 'granted'
28    )
29  ) {
30    await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE);
31    await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);
32  }
33
34  /** 初始化路径 */
35  await setupFolder();
36  // 加载配置
37  await loadConfig();
38  // 加载插件
39  try {
40    await TrackPlayer.setupPlayer();
41  } catch (e: any) {
42    if (
43      e?.message !== 'The player has already been initialized via setupPlayer.'
44    ) {
45      throw e;
46    }
47  }
48
49  Promise.all([
50    await pluginManager.setupPlugins(),
51    await MediaMetaManager.setupMediaMeta(),
52  ]);
53  await TrackPlayer.updateOptions({
54    progressUpdateEventInterval: 0.4,
55    stopWithApp: false,
56    alwaysPauseOnInterruption: true,
57    capabilities: [
58      Capability.Play,
59      Capability.Pause,
60      Capability.SkipToNext,
61      Capability.SkipToPrevious,
62    ],
63    compactCapabilities: [
64      Capability.Play,
65      Capability.Pause,
66      Capability.SkipToNext,
67      Capability.SkipToPrevious,
68    ],
69    notificationCapabilities: [
70      Capability.Play,
71      Capability.Pause,
72      Capability.SkipToNext,
73      Capability.SkipToPrevious,
74    ],
75  });
76  await MusicQueue.setupMusicQueue();
77  await MusicSheet.setupMusicSheet();
78  await DownloadManager.setupDownload();
79
80  ErrorUtils.setGlobalHandler(error => {
81    errorLog('未捕获的错误', error);
82  });
83}
84
85/** 初始化 */
86async function setupFolder() {
87  await Promise.all([
88    checkAndCreateDir(pathConst.dataPath),
89    checkAndCreateDir(pathConst.logPath),
90    checkAndCreateDir(pathConst.cachePath),
91    checkAndCreateDir(pathConst.storagePath),
92    checkAndCreateDir(pathConst.pluginPath),
93    checkAndCreateDir(pathConst.lrcCachePath),
94  ]);
95}
96
97export default async function () {
98  try {
99    await _bootstrap();
100  } catch (e) {
101    errorLog('初始化出错', e);
102    console.log(e);
103  }
104  // 隐藏开屏动画
105  console.log('HIDE');
106  RNBootSplash.hide({fade: true});
107}
108