xref: /MusicFree/src/entry/bootstrap.ts (revision 43eb30bf16ea88ab8e3cdff98faf307c8c8f93d3)
1e14deecfS猫头猫import MusicSheet from '@/core/musicSheet';
2bf6e62f2S猫头猫import {check, PERMISSIONS, request} from 'react-native-permissions';
35500cea7S猫头猫import RNTrackPlayer, {
45500cea7S猫头猫    AppKilledPlaybackBehavior,
55500cea7S猫头猫    Capability,
65500cea7S猫头猫} from 'react-native-track-player';
7bf6e62f2S猫头猫import 'react-native-get-random-values';
8e22d5e4fS猫头猫import Config from '@/core/config';
90d39db21S猫头猫import RNBootSplash from 'react-native-bootsplash';
106780f402S猫头猫import pathConst from '@/constants/pathConst';
11be0a3650S猫头猫import {checkAndCreateDir} from '@/utils/fileUtils';
121e263108S猫头猫import {errorLog, trace} from '@/utils/log';
13*43eb30bfS猫头猫import MediaMeta from '@/core/mediaMeta.old';
14*43eb30bfS猫头猫import Cache from '@/core/cache.old';
15927dbe93S猫头猫import PluginManager from '@/core/pluginManager';
16ef714860S猫头猫import Network from '@/core/network';
17c30d30e1S猫头猫import {ImgAsset} from '@/constants/assetsConst';
180e4173cdS猫头猫import LocalMusicSheet from '@/core/localMusicSheet';
199c72192fS猫头猫import {Linking} from 'react-native';
20a27adc20S猫头猫import Theme from '@/core/theme';
2157277364S猫头猫import LyricManager from '@/core/lyricManager';
22b3a3a048S猫头猫import {getStorage, setStorage} from '@/utils/storage';
23a84a85c5S猫头猫import Toast from '@/utils/toast';
24a84a85c5S猫头猫import {localPluginHash, supportLocalMediaType} from '@/constants/commonConst';
255500cea7S猫头猫import TrackPlayer from '@/core/trackPlayer';
265500cea7S猫头猫import musicHistory from '@/core/musicHistory';
27bf6e62f2S猫头猫
288b88e961S猫头猫/** app加载前执行
298b88e961S猫头猫 * 1. 检查权限
308b88e961S猫头猫 * 2. 数据初始化
318b88e961S猫头猫 * 3.
328b88e961S猫头猫 */
3394a1b1fcS猫头猫async function _bootstrap() {
34927dbe93S猫头猫    // 1. 检查权限
35bf6e62f2S猫头猫    const [readStoragePermission, writeStoragePermission] = await Promise.all([
36bf6e62f2S猫头猫        check(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE),
37bf6e62f2S猫头猫        check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE),
38bf6e62f2S猫头猫    ]);
39bf6e62f2S猫头猫    if (
40bf6e62f2S猫头猫        !(
41bf6e62f2S猫头猫            readStoragePermission === 'granted' &&
42bf6e62f2S猫头猫            writeStoragePermission === 'granted'
43bf6e62f2S猫头猫        )
44bf6e62f2S猫头猫    ) {
45bf6e62f2S猫头猫        await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE);
46bf6e62f2S猫头猫        await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);
47bf6e62f2S猫头猫    }
48bf6e62f2S猫头猫
49927dbe93S猫头猫    // 2. 数据初始化
506780f402S猫头猫    /** 初始化路径 */
516780f402S猫头猫    await setupFolder();
521e263108S猫头猫    trace('文件夹初始化完成');
53bf6e62f2S猫头猫    // 加载配置
54ef714860S猫头猫    await Promise.all([
55ef714860S猫头猫        Config.setup(),
56ef714860S猫头猫        MediaMeta.setup(),
57ef714860S猫头猫        MusicSheet.setup(),
58ef714860S猫头猫        Network.setup(),
595500cea7S猫头猫        musicHistory.setupMusicHistory(),
60ef714860S猫头猫    ]);
611e263108S猫头猫    trace('配置初始化完成');
62bf6e62f2S猫头猫    // 加载插件
6394a1b1fcS猫头猫    try {
645500cea7S猫头猫        await RNTrackPlayer.setupPlayer({
65b882a19dS猫头猫            maxCacheSize:
66b882a19dS猫头猫                Config.get('setting.basic.maxCacheSize') ?? 1024 * 1024 * 512,
67cfa0fc07S猫头猫        });
6894a1b1fcS猫头猫    } catch (e: any) {
6994a1b1fcS猫头猫        if (
704060c00aS猫头猫            e?.message !==
714060c00aS猫头猫            'The player has already been initialized via setupPlayer.'
7294a1b1fcS猫头猫        ) {
7394a1b1fcS猫头猫            throw e;
7494a1b1fcS猫头猫        }
7594a1b1fcS猫头猫    }
765500cea7S猫头猫    await RNTrackPlayer.updateOptions({
772aa88193S猫头猫        icon: ImgAsset.logoTransparent,
78e2257bd6S猫头猫        progressUpdateEventInterval: 1,
795500cea7S猫头猫        android: {
805500cea7S猫头猫            alwaysPauseOnInterruption: true,
815500cea7S猫头猫            appKilledPlaybackBehavior:
825500cea7S猫头猫                AppKilledPlaybackBehavior.ContinuePlayback,
835500cea7S猫头猫        },
84bf6e62f2S猫头猫        capabilities: [
85bf6e62f2S猫头猫            Capability.Play,
86bf6e62f2S猫头猫            Capability.Pause,
87bf6e62f2S猫头猫            Capability.SkipToNext,
88bf6e62f2S猫头猫            Capability.SkipToPrevious,
89bf6e62f2S猫头猫        ],
90bf6e62f2S猫头猫        compactCapabilities: [
91bf6e62f2S猫头猫            Capability.Play,
92bf6e62f2S猫头猫            Capability.Pause,
93bf6e62f2S猫头猫            Capability.SkipToNext,
94bf6e62f2S猫头猫            Capability.SkipToPrevious,
95bf6e62f2S猫头猫        ],
96bf6e62f2S猫头猫        notificationCapabilities: [
97bf6e62f2S猫头猫            Capability.Play,
98bf6e62f2S猫头猫            Capability.Pause,
99bf6e62f2S猫头猫            Capability.SkipToNext,
100bf6e62f2S猫头猫            Capability.SkipToPrevious,
1010d39db21S猫头猫        ],
1020d39db21S猫头猫    });
1031e263108S猫头猫    trace('播放器初始化完成');
1044060c00aS猫头猫    await Cache.setup();
1051e263108S猫头猫    trace('缓存初始化完成');
1068b88e961S猫头猫    await PluginManager.setup();
1071e263108S猫头猫    trace('插件初始化完成');
1085500cea7S猫头猫    await TrackPlayer.setupTrackPlayer();
1091e263108S猫头猫    trace('播放列表初始化完成');
1100e4173cdS猫头猫    await LocalMusicSheet.setup();
1110e4173cdS猫头猫    trace('本地音乐初始化完成');
112a27adc20S猫头猫    Theme.setup();
113a27adc20S猫头猫    trace('主题初始化完成');
11457277364S猫头猫    await LyricManager.setup();
1158b88e961S猫头猫
116b3a3a048S猫头猫    extraMakeup();
117c79c8a57S猫头猫    ErrorUtils.setGlobalHandler(error => {
118c79c8a57S猫头猫        errorLog('未捕获的错误', error);
119c79c8a57S猫头猫    });
120bf6e62f2S猫头猫}
1216c6f45bdS猫头猫
1226c6f45bdS猫头猫/** 初始化 */
1236c6f45bdS猫头猫async function setupFolder() {
1246780f402S猫头猫    await Promise.all([
125be0a3650S猫头猫        checkAndCreateDir(pathConst.dataPath),
1267f771613S猫头猫        checkAndCreateDir(pathConst.logPath),
1277f771613S猫头猫        checkAndCreateDir(pathConst.cachePath),
128c79c8a57S猫头猫        checkAndCreateDir(pathConst.pluginPath),
12994a1b1fcS猫头猫        checkAndCreateDir(pathConst.lrcCachePath),
1300e4173cdS猫头猫        checkAndCreateDir(pathConst.downloadPath).then(() => {
1310e4173cdS猫头猫            checkAndCreateDir(pathConst.downloadMusicPath);
1320e4173cdS猫头猫        }),
1336780f402S猫头猫    ]);
1346c6f45bdS猫头猫}
13594a1b1fcS猫头猫
13694a1b1fcS猫头猫export default async function () {
13794a1b1fcS猫头猫    try {
13894a1b1fcS猫头猫        await _bootstrap();
13994a1b1fcS猫头猫    } catch (e) {
14094a1b1fcS猫头猫        errorLog('初始化出错', e);
14194a1b1fcS猫头猫    }
14294a1b1fcS猫头猫    // 隐藏开屏动画
14394a1b1fcS猫头猫    console.log('HIDE');
14494a1b1fcS猫头猫    RNBootSplash.hide({fade: true});
14594a1b1fcS猫头猫}
146b3a3a048S猫头猫
147b3a3a048S猫头猫/** 不需要阻塞的 */
148b3a3a048S猫头猫async function extraMakeup() {
149a84a85c5S猫头猫    // 自动更新
150b3a3a048S猫头猫    try {
151b3a3a048S猫头猫        if (Config.get('setting.basic.autoUpdatePlugin')) {
152b3a3a048S猫头猫            const lastUpdated =
153b3a3a048S猫头猫                (await getStorage('pluginLastupdatedTime')) || 0;
154b3a3a048S猫头猫            const now = Date.now();
155b3a3a048S猫头猫            if (Math.abs(now - lastUpdated) > 86400000) {
156b3a3a048S猫头猫                setStorage('pluginLastupdatedTime', now);
157b3a3a048S猫头猫                const plugins = PluginManager.getValidPlugins();
158b3a3a048S猫头猫                for (let i = 0; i < plugins.length; ++i) {
159b3a3a048S猫头猫                    const srcUrl = plugins[i].instance.srcUrl;
160b3a3a048S猫头猫                    if (srcUrl) {
161b3a3a048S猫头猫                        await PluginManager.installPluginFromUrl(srcUrl);
162b3a3a048S猫头猫                    }
163b3a3a048S猫头猫                }
164b3a3a048S猫头猫            }
165b3a3a048S猫头猫        }
166b3a3a048S猫头猫    } catch {}
167a84a85c5S猫头猫
168a84a85c5S猫头猫    async function handleLinkingUrl(url: string) {
169a84a85c5S猫头猫        // 插件
170a84a85c5S猫头猫        try {
171a84a85c5S猫头猫            if (url.endsWith('.js')) {
172e36e2599S猫头猫                PluginManager.installPlugin(url, {
173e36e2599S猫头猫                    notCheckVersion: Config.get(
174e36e2599S猫头猫                        'setting.basic.notCheckPluginVersion',
175e36e2599S猫头猫                    ),
176e36e2599S猫头猫                })
177a84a85c5S猫头猫                    .then(res => {
178a84a85c5S猫头猫                        Toast.success(`插件「${res.name}」安装成功~`);
179a84a85c5S猫头猫                    })
180a84a85c5S猫头猫                    .catch(e => {
181a84a85c5S猫头猫                        console.log(e);
182a84a85c5S猫头猫                        Toast.warn(e?.message ?? '无法识别此插件');
183a84a85c5S猫头猫                    });
184a84a85c5S猫头猫            } else if (supportLocalMediaType.some(it => url.endsWith(it))) {
185a84a85c5S猫头猫                // 本地播放
186a84a85c5S猫头猫                const musicItem = await PluginManager.getByHash(
187a84a85c5S猫头猫                    localPluginHash,
188a84a85c5S猫头猫                )?.instance?.importMusicItem?.(url);
189a84a85c5S猫头猫                console.log(musicItem);
190a84a85c5S猫头猫                if (musicItem) {
1915500cea7S猫头猫                    TrackPlayer.play(musicItem);
192a84a85c5S猫头猫                }
193a84a85c5S猫头猫            }
194a84a85c5S猫头猫        } catch {}
195a84a85c5S猫头猫    }
196a84a85c5S猫头猫
197a84a85c5S猫头猫    // 开启监听
198a84a85c5S猫头猫    Linking.addEventListener('url', data => {
199a84a85c5S猫头猫        if (data.url) {
200a84a85c5S猫头猫            handleLinkingUrl(data.url);
201a84a85c5S猫头猫        }
202a84a85c5S猫头猫    });
203a84a85c5S猫头猫    const initUrl = await Linking.getInitialURL();
204a84a85c5S猫头猫    if (initUrl) {
205a84a85c5S猫头猫        handleLinkingUrl(initUrl);
206a84a85c5S猫头猫    }
207aaa0db32S猫头猫
208aaa0db32S猫头猫    if (Config.get('setting.basic.autoPlayWhenAppStart')) {
2095500cea7S猫头猫        TrackPlayer.play();
210aaa0db32S猫头猫    }
211b3a3a048S猫头猫}
212