1// @ts-ignore: uses flow
2import normalizeColor from '@react-native/normalize-color';
3import { ExpoConfig } from 'expo/config';
4import { ConfigPlugin, InfoPlist, withInfoPlist } from 'expo/config-plugins';
5
6// Maps to the template AppDelegate.m
7const BACKGROUND_COLOR_KEY = 'RCTRootViewBackgroundColor';
8
9const debug = require('debug')('expo:system-ui:plugin:ios');
10
11export const withIosRootViewBackgroundColor: ConfigPlugin = (config) => {
12  config = withInfoPlist(config, (config) => {
13    config.modResults = setRootViewBackgroundColor(config, config.modResults);
14    return config;
15  });
16  return config;
17};
18
19export function setRootViewBackgroundColor(
20  config: Pick<ExpoConfig, 'backgroundColor' | 'ios'>,
21  infoPlist: InfoPlist
22): InfoPlist {
23  const backgroundColor = getRootViewBackgroundColor(config);
24  if (!backgroundColor) {
25    delete infoPlist[BACKGROUND_COLOR_KEY];
26  } else {
27    let color = normalizeColor(backgroundColor);
28    if (!color) {
29      throw new Error('Invalid background color on iOS');
30    }
31    color = ((color << 24) | (color >>> 8)) >>> 0;
32    infoPlist[BACKGROUND_COLOR_KEY] = color;
33
34    debug(`Convert color: ${backgroundColor} -> ${color}`);
35  }
36  return infoPlist;
37}
38
39export function getRootViewBackgroundColor(config: Pick<ExpoConfig, 'ios' | 'backgroundColor'>) {
40  return config.ios?.backgroundColor || config.backgroundColor || null;
41}
42