1import { withMod } from './withMod';
2import { ConfigPlugin, ExportedConfigWithProps, Mod } from '../Plugin.types';
3import { Manifest, Paths, Properties, Resources } from '../android';
4
5type OptionalPromise<T> = T | Promise<T>;
6
7type MutateDataAction<T> = (expo: ExportedConfigWithProps<T>, data: T) => OptionalPromise<T>;
8
9/**
10 * Helper method for creating mods from existing config functions.
11 *
12 * @param action
13 */
14export function createAndroidManifestPlugin(
15  action: MutateDataAction<Manifest.AndroidManifest>,
16  name: string
17): ConfigPlugin {
18  const withUnknown: ConfigPlugin = (config) =>
19    withAndroidManifest(config, async (config) => {
20      config.modResults = await action(config, config.modResults);
21      return config;
22    });
23  if (name) {
24    Object.defineProperty(withUnknown, 'name', {
25      value: name,
26    });
27  }
28  return withUnknown;
29}
30
31export function createStringsXmlPlugin(
32  action: MutateDataAction<Resources.ResourceXML>,
33  name: string
34): ConfigPlugin {
35  const withUnknown: ConfigPlugin = (config) =>
36    withStringsXml(config, async (config) => {
37      config.modResults = await action(config, config.modResults);
38      return config;
39    });
40  if (name) {
41    Object.defineProperty(withUnknown, 'name', {
42      value: name,
43    });
44  }
45  return withUnknown;
46}
47
48/**
49 * Provides the AndroidManifest.xml for modification.
50 *
51 * @param config
52 * @param action
53 */
54export const withAndroidManifest: ConfigPlugin<Mod<Manifest.AndroidManifest>> = (
55  config,
56  action
57) => {
58  return withMod(config, {
59    platform: 'android',
60    mod: 'manifest',
61    action,
62  });
63};
64
65/**
66 * Provides the strings.xml for modification.
67 *
68 * @param config
69 * @param action
70 */
71export const withStringsXml: ConfigPlugin<Mod<Resources.ResourceXML>> = (config, action) => {
72  return withMod(config, {
73    platform: 'android',
74    mod: 'strings',
75    action,
76  });
77};
78
79/**
80 * Provides the `android/app/src/main/res/values/colors.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
81 *
82 * @param config
83 * @param action
84 */
85export const withAndroidColors: ConfigPlugin<Mod<Resources.ResourceXML>> = (config, action) => {
86  return withMod(config, {
87    platform: 'android',
88    mod: 'colors',
89    action,
90  });
91};
92
93/**
94 * Provides the `android/app/src/main/res/values-night/colors.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
95 *
96 * @param config
97 * @param action
98 */
99export const withAndroidColorsNight: ConfigPlugin<Mod<Resources.ResourceXML>> = (
100  config,
101  action
102) => {
103  return withMod(config, {
104    platform: 'android',
105    mod: 'colorsNight',
106    action,
107  });
108};
109
110/**
111 * Provides the `android/app/src/main/res/values/styles.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)).
112 *
113 * @param config
114 * @param action
115 */
116export const withAndroidStyles: ConfigPlugin<Mod<Resources.ResourceXML>> = (config, action) => {
117  return withMod(config, {
118    platform: 'android',
119    mod: 'styles',
120    action,
121  });
122};
123
124/**
125 * Provides the project MainActivity for modification.
126 *
127 * @param config
128 * @param action
129 */
130export const withMainActivity: ConfigPlugin<Mod<Paths.ApplicationProjectFile>> = (
131  config,
132  action
133) => {
134  return withMod(config, {
135    platform: 'android',
136    mod: 'mainActivity',
137    action,
138  });
139};
140
141/**
142 * Provides the project MainApplication for modification.
143 *
144 * @param config
145 * @param action
146 */
147export const withMainApplication: ConfigPlugin<Mod<Paths.ApplicationProjectFile>> = (
148  config,
149  action
150) => {
151  return withMod(config, {
152    platform: 'android',
153    mod: 'mainApplication',
154    action,
155  });
156};
157
158/**
159 * Provides the project /build.gradle for modification.
160 *
161 * @param config
162 * @param action
163 */
164export const withProjectBuildGradle: ConfigPlugin<Mod<Paths.GradleProjectFile>> = (
165  config,
166  action
167) => {
168  return withMod(config, {
169    platform: 'android',
170    mod: 'projectBuildGradle',
171    action,
172  });
173};
174
175/**
176 * Provides the app/build.gradle for modification.
177 *
178 * @param config
179 * @param action
180 */
181export const withAppBuildGradle: ConfigPlugin<Mod<Paths.GradleProjectFile>> = (config, action) => {
182  return withMod(config, {
183    platform: 'android',
184    mod: 'appBuildGradle',
185    action,
186  });
187};
188
189/**
190 * Provides the /settings.gradle for modification.
191 *
192 * @param config
193 * @param action
194 */
195export const withSettingsGradle: ConfigPlugin<Mod<Paths.GradleProjectFile>> = (config, action) => {
196  return withMod(config, {
197    platform: 'android',
198    mod: 'settingsGradle',
199    action,
200  });
201};
202
203/**
204 * Provides the /gradle.properties for modification.
205 *
206 * @param config
207 * @param action
208 */
209export const withGradleProperties: ConfigPlugin<Mod<Properties.PropertiesItem[]>> = (
210  config,
211  action
212) => {
213  return withMod(config, {
214    platform: 'android',
215    mod: 'gradleProperties',
216    action,
217  });
218};
219