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