113c5c8bdSEvan Baconimport assert from 'assert';
2*435bbba8SBrent Vatneimport { ExpoConfig } from 'expo/config';
3*435bbba8SBrent Vatneimport { AndroidConfig, ConfigPlugin, withStringsXml } from 'expo/config-plugins';
413c5c8bdSEvan Bacon
513c5c8bdSEvan Baconexport type Props = {
613c5c8bdSEvan Bacon  userInterfaceStyle?: ExpoConfig['userInterfaceStyle'];
713c5c8bdSEvan Bacon};
813c5c8bdSEvan Bacon
913c5c8bdSEvan Bacon// strings.xml keys, this should not change.
1013c5c8bdSEvan Baconconst USER_INTERFACE_STYLE_KEY = 'expo_system_ui_user_interface_style';
1113c5c8bdSEvan Bacon
1213c5c8bdSEvan Baconexport const withAndroidUserInterfaceStyle: ConfigPlugin<void> = (config) => {
1313c5c8bdSEvan Bacon  return withStringsXml(config, (config) => {
1413c5c8bdSEvan Bacon    config.modResults = setStrings(config.modResults, resolveProps(config));
1513c5c8bdSEvan Bacon    return config;
1613c5c8bdSEvan Bacon  });
1713c5c8bdSEvan Bacon};
1813c5c8bdSEvan Bacon
1913c5c8bdSEvan Baconexport function resolveProps(config: Pick<ExpoConfig, 'userInterfaceStyle' | 'android'>): Props {
2013c5c8bdSEvan Bacon  const userInterfaceStyle = config.android?.userInterfaceStyle ?? config.userInterfaceStyle;
2113c5c8bdSEvan Bacon
2213c5c8bdSEvan Bacon  assert(
2313c5c8bdSEvan Bacon    !userInterfaceStyle || ['automatic', 'light', 'dark'].includes(userInterfaceStyle),
2413c5c8bdSEvan Bacon    `expo-system-ui: Invalid userInterfaceStyle: "${userInterfaceStyle}"`
2513c5c8bdSEvan Bacon  );
2613c5c8bdSEvan Bacon
2713c5c8bdSEvan Bacon  return { userInterfaceStyle };
2813c5c8bdSEvan Bacon}
2913c5c8bdSEvan Bacon
3013c5c8bdSEvan Baconexport function setStrings(
3113c5c8bdSEvan Bacon  strings: AndroidConfig.Resources.ResourceXML,
3213c5c8bdSEvan Bacon  { userInterfaceStyle }: Props
3313c5c8bdSEvan Bacon): AndroidConfig.Resources.ResourceXML {
3413c5c8bdSEvan Bacon  const pairs = [[USER_INTERFACE_STYLE_KEY, userInterfaceStyle]] as [string, any][];
3513c5c8bdSEvan Bacon
3613c5c8bdSEvan Bacon  const stringItems: AndroidConfig.Resources.ResourceItemXML[] = [];
3713c5c8bdSEvan Bacon  for (const [key, value] of pairs) {
3813c5c8bdSEvan Bacon    if (value == null) {
3913c5c8bdSEvan Bacon      // Since we're using custom strings, we can remove them for convenience between prebuilds.
4013c5c8bdSEvan Bacon      strings = AndroidConfig.Strings.removeStringItem(key, strings);
4113c5c8bdSEvan Bacon    } else {
4213c5c8bdSEvan Bacon      stringItems.push(
4313c5c8bdSEvan Bacon        AndroidConfig.Resources.buildResourceItem({
4413c5c8bdSEvan Bacon          name: key,
4513c5c8bdSEvan Bacon          value: String(value),
4613c5c8bdSEvan Bacon          translatable: false,
4713c5c8bdSEvan Bacon        })
4813c5c8bdSEvan Bacon      );
4913c5c8bdSEvan Bacon    }
5013c5c8bdSEvan Bacon  }
5113c5c8bdSEvan Bacon
5213c5c8bdSEvan Bacon  return AndroidConfig.Strings.setStringItem(stringItems, strings);
5313c5c8bdSEvan Bacon}
54