1import { ConfigPlugin, WarningAggregator, withPlugins } from '@expo/config-plugins';
2import { ExpoConfig } from '@expo/config-types';
3import JsonFile from '@expo/json-file';
4import resolveFrom from 'resolve-from';
5import semver from 'semver';
6
7import { getAndroidSplashConfig } from './getAndroidSplashConfig';
8import { withAndroidSplashDrawables } from './withAndroidSplashDrawables';
9import { withAndroidSplashImages } from './withAndroidSplashImages';
10import { withAndroidSplashLegacyMainActivity } from './withAndroidSplashLegacyMainActivity';
11import { withAndroidSplashStrings } from './withAndroidSplashStrings';
12import { withAndroidSplashStyles } from './withAndroidSplashStyles';
13
14export const withAndroidSplashScreen: ConfigPlugin = (config) => {
15  const splashConfig = getAndroidSplashConfig(config);
16
17  // Update the android status bar to match the splash screen
18  // androidStatusBar applies info to the app activity style.
19  const backgroundColor = splashConfig?.backgroundColor || '#ffffff';
20  if (config.androidStatusBar?.backgroundColor) {
21    if (
22      backgroundColor.toLowerCase() !== config.androidStatusBar?.backgroundColor?.toLowerCase?.()
23    ) {
24      WarningAggregator.addWarningAndroid(
25        'androidStatusBar.backgroundColor',
26        'Color conflicts with the splash.backgroundColor'
27      );
28    }
29  } else {
30    if (!config.androidStatusBar) config.androidStatusBar = {};
31    config.androidStatusBar.backgroundColor = backgroundColor;
32  }
33
34  return withPlugins(config, [
35    withAndroidSplashImages,
36    [withAndroidSplashDrawables, splashConfig],
37    ...(shouldUpdateLegacyMainActivity(config) ? [withAndroidSplashLegacyMainActivity] : []),
38    withAndroidSplashStyles,
39    withAndroidSplashStrings,
40  ]);
41};
42
43function shouldUpdateLegacyMainActivity(config: ExpoConfig): boolean {
44  try {
45    const projectRoot = config._internal?.projectRoot;
46    const packagePath = resolveFrom(projectRoot, 'expo-splash-screen/package.json');
47    if (packagePath) {
48      const version = JsonFile.read(packagePath).version?.toString() ?? '';
49      return semver.lt(version, '0.12.0');
50    }
51    // If expo-splash-screen didn't be installed or included in template, we check the sdkVersion instead.
52    return !!(config.sdkVersion && semver.lt(config.sdkVersion, '43.0.0'));
53  } catch {}
54  return false;
55}
56