xref: /MusicFree/src/entry/bootstrap.ts (revision a84a85c5181b457562342bf0bf1cf44d23df849b)
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