1import { ConfigPlugin, withMainActivity } from '@expo/config-plugins'; 2import { addImports } from '@expo/config-plugins/build/android/codeMod'; 3import { mergeContents, removeContents } from '@expo/config-plugins/build/utils/generateCode'; 4import { ExpoConfig } from '@expo/config-types'; 5import Debug from 'debug'; 6 7import { getAndroidSplashConfig } from './getAndroidSplashConfig'; 8 9const debug = Debug('expo:prebuild-config:expo-splash-screen:android:mainActivity'); 10 11// DO NOT CHANGE 12const SHOW_SPLASH_ID = 'expo-splash-screen-mainActivity-onCreate-show-splash'; 13 14export const withAndroidSplashLegacyMainActivity: ConfigPlugin = (config) => { 15 return withMainActivity(config, (config) => { 16 config.modResults.contents = setSplashScreenLegacyMainActivity( 17 config, 18 config.modResults.contents, 19 config.modResults.language 20 ); 21 return config; 22 }); 23}; 24 25export function setSplashScreenLegacyMainActivity( 26 config: Pick<ExpoConfig, 'android' | 'androidStatusBar' | 'userInterfaceStyle'>, 27 mainActivity: string, 28 language: 'java' | 'kt' 29): string { 30 debug(`Modify with language: "${language}"`); 31 const splashConfig = getAndroidSplashConfig(config); 32 33 if (!splashConfig) { 34 // Remove our generated code safely... 35 const mod = removeContents({ 36 src: mainActivity, 37 tag: SHOW_SPLASH_ID, 38 }); 39 40 mainActivity = mod.contents; 41 if (mod.didClear) { 42 debug('Removed SplashScreen.show()'); 43 } 44 return mainActivity; 45 } 46 // TODO: Translucent is weird 47 const statusBarTranslucent = !!config.androidStatusBar?.translucent; 48 49 const { resizeMode } = splashConfig; 50 const isJava = language === 'java'; 51 const LE = isJava ? ';' : ''; 52 53 mainActivity = addImports( 54 mainActivity, 55 [ 56 'expo.modules.splashscreen.SplashScreen', 57 'expo.modules.splashscreen.SplashScreenImageResizeMode', 58 'android.os.Bundle', 59 ], 60 isJava 61 ); 62 63 if (!mainActivity.match(/(?<=^.*super\.onCreate.*$)/m)) { 64 const onCreateBlock = isJava 65 ? [ 66 ' @Override', 67 ' protected void onCreate(Bundle savedInstanceState) {', 68 ' super.onCreate(savedInstanceState);', 69 ' }', 70 ] 71 : [ 72 ' override fun onCreate(savedInstanceState: Bundle?) {', 73 ' super.onCreate(savedInstanceState)', 74 ' }', 75 ]; 76 77 mainActivity = mergeContents({ 78 src: mainActivity, 79 // insert just below super.onCreate 80 anchor: isJava 81 ? /(?<=public\s+class\s+.*\s+extends\s+.*\s+{.*$)/m 82 : /(?<=class\s+.*\s+:\s+.*\s+{.*$)/m, 83 offset: 1, 84 comment: '//', 85 tag: 'expo-splash-screen-mainActivity-onCreate', 86 newSrc: onCreateBlock.join('\n'), 87 }).contents; 88 } 89 90 // Remove our generated code safely... 91 mainActivity = removeContents({ 92 src: mainActivity, 93 tag: SHOW_SPLASH_ID, 94 }).contents; 95 96 // Remove code from `@expo/configure-splash-screen` 97 mainActivity = mainActivity 98 .split('\n') 99 .filter((line) => { 100 return !/SplashScreen\.show\(this,\s?SplashScreenImageResizeMode\./.test(line); 101 }) 102 .join('\n'); 103 104 // Reapply generated code. 105 mainActivity = mergeContents({ 106 src: mainActivity, 107 // insert just below super.onCreate 108 anchor: /(?<=^.*super\.onCreate.*$)/m, 109 offset: 1, 110 comment: '//', 111 tag: SHOW_SPLASH_ID, 112 newSrc: ` SplashScreen.show(this, SplashScreenImageResizeMode.${resizeMode.toUpperCase()}, ReactRootView${ 113 isJava ? '.class' : '::class.java' 114 }, ${statusBarTranslucent})${LE}`, 115 }).contents; 116 117 // TODO: Remove old `SplashScreen.show` 118 119 return mainActivity; 120} 121