xref: /MusicFree/src/entry/bootstrap.ts (revision 2aa881935ca35b8fb1abc4206e0dc35149231456)
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 'react-native-get-random-values';
6import Config from '@/core/config';
7import RNBootSplash from 'react-native-bootsplash';
8import pathConst from '@/constants/pathConst';
9import {checkAndCreateDir} from '@/utils/fileUtils';
10import {errorLog, trace} from '@/utils/log';
11import MediaMeta from '@/core/mediaMeta';
12import Cache from '@/core/cache';
13import PluginManager from '@/core/pluginManager';
14import Network from '@/core/network';
15import {ImgAsset} from '@/constants/assetsConst';
16import LocalMusicSheet from '@/core/localMusicSheet';
17import {StatusBar} from 'react-native';
18
19/** app加载前执行
20 * 1. 检查权限
21 * 2. 数据初始化
22 * 3.
23 */
24async function _bootstrap() {
25    // 1. 检查权限
26    const [readStoragePermission, writeStoragePermission] = await Promise.all([
27        check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE),
28        check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE),
29    ]);
30    if (
31        !(
32            readStoragePermission === 'granted' &&
33            writeStoragePermission === 'granted'
34        )
35    ) {
36        await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE);
37        await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);
38    }
39
40    // 2. 数据初始化
41    /** 初始化路径 */
42    await setupFolder();
43    trace('文件夹初始化完成');
44    // 加载配置
45    await Promise.all([
46        Config.setup(),
47        MediaMeta.setup(),
48        MusicSheet.setup(),
49        Network.setup(),
50    ]);
51    trace('配置初始化完成');
52    // 加载插件
53    try {
54        await TrackPlayer.setupPlayer({
55            maxCacheSize:
56                Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512,
57        });
58    } catch (e: any) {
59        if (
60            e?.message !==
61            'The player has already been initialized via setupPlayer.'
62        ) {
63            throw e;
64        }
65    }
66    await TrackPlayer.updateOptions({
67        icon: ImgAsset.logoTransparent,
68        progressUpdateEventInterval: 1,
69        alwaysPauseOnInterruption: true,
70        capabilities: [
71            Capability.Play,
72            Capability.Pause,
73            Capability.SkipToNext,
74            Capability.SkipToPrevious,
75        ],
76        compactCapabilities: [
77            Capability.Play,
78            Capability.Pause,
79            Capability.SkipToNext,
80            Capability.SkipToPrevious,
81        ],
82        notificationCapabilities: [
83            Capability.Play,
84            Capability.Pause,
85            Capability.SkipToNext,
86            Capability.SkipToPrevious,
87        ],
88    });
89    trace('播放器初始化完成');
90    await Cache.setup();
91    trace('缓存初始化完成');
92    await PluginManager.setup();
93    trace('插件初始化完成');
94    await MusicQueue.setup();
95    trace('播放列表初始化完成');
96    await LocalMusicSheet.setup();
97    trace('本地音乐初始化完成');
98
99    StatusBar.setBackgroundColor('transparent');
100    StatusBar.setTranslucent(true);
101
102    ErrorUtils.setGlobalHandler(error => {
103        errorLog('未捕获的错误', error);
104    });
105}
106
107/** 初始化 */
108async function setupFolder() {
109    await Promise.all([
110        checkAndCreateDir(pathConst.dataPath),
111        checkAndCreateDir(pathConst.logPath),
112        checkAndCreateDir(pathConst.cachePath),
113        checkAndCreateDir(pathConst.pluginPath),
114        checkAndCreateDir(pathConst.lrcCachePath),
115        checkAndCreateDir(pathConst.downloadPath).then(() => {
116            checkAndCreateDir(pathConst.downloadMusicPath);
117        }),
118    ]);
119}
120
121export default async function () {
122    try {
123        await _bootstrap();
124    } catch (e) {
125        errorLog('初始化出错', e);
126        console.log(e);
127    }
128    // 隐藏开屏动画
129    console.log('HIDE');
130    RNBootSplash.hide({fade: true});
131}
132