react-native-bootsplash 7.0.2 → 7.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.plugin.js +1 -1
- package/cli.js +1 -1
- package/dist/commonjs/extras/addon/index.js +97 -0
- package/dist/commonjs/extras/addon/index.js.map +1 -0
- package/dist/commonjs/{expo.js → extras/expo.js} +29 -32
- package/dist/commonjs/extras/expo.js.map +1 -0
- package/dist/commonjs/extras/generate.js +274 -0
- package/dist/commonjs/extras/generate.js.map +1 -0
- package/dist/commonjs/{generate.js → extras/utils.js} +126 -355
- package/dist/commonjs/extras/utils.js.map +1 -0
- package/dist/commonjs/package.json +1 -0
- package/dist/module/extras/addon/index.js +97 -0
- package/dist/module/extras/addon/index.js.map +1 -0
- package/dist/module/{expo.js → extras/expo.js} +7 -11
- package/dist/module/extras/expo.js.map +1 -0
- package/dist/module/extras/generate.js +267 -0
- package/dist/module/extras/generate.js.map +1 -0
- package/dist/module/{generate.js → extras/utils.js} +115 -343
- package/dist/module/extras/utils.js.map +1 -0
- package/dist/module/package.json +1 -0
- package/dist/typescript/{addon → commonjs/extras/addon}/index.d.ts +1 -1
- package/dist/typescript/commonjs/extras/addon/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/extras/expo.d.ts +8 -0
- package/dist/typescript/commonjs/extras/expo.d.ts.map +1 -0
- package/dist/typescript/commonjs/extras/generate.d.ts +17 -0
- package/dist/typescript/commonjs/extras/generate.d.ts.map +1 -0
- package/dist/typescript/{generate.d.ts → commonjs/extras/utils.d.ts} +67 -37
- package/dist/typescript/commonjs/extras/utils.d.ts.map +1 -0
- package/dist/typescript/commonjs/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/package.json +1 -0
- package/dist/typescript/commonjs/specs/NativeRNBootSplash.d.ts.map +1 -0
- package/dist/typescript/commonjs/specs/NativeRNBootSplash.web.d.ts.map +1 -0
- package/dist/typescript/module/extras/addon/index.d.ts +26 -0
- package/dist/typescript/module/extras/addon/index.d.ts.map +1 -0
- package/dist/typescript/module/extras/expo.d.ts +8 -0
- package/dist/typescript/module/extras/expo.d.ts.map +1 -0
- package/dist/typescript/module/extras/generate.d.ts +17 -0
- package/dist/typescript/module/extras/generate.d.ts.map +1 -0
- package/dist/typescript/module/extras/utils.d.ts +192 -0
- package/dist/typescript/module/extras/utils.d.ts.map +1 -0
- package/dist/typescript/module/index.d.ts +61 -0
- package/dist/typescript/module/index.d.ts.map +1 -0
- package/dist/typescript/module/package.json +1 -0
- package/dist/typescript/module/specs/NativeRNBootSplash.d.ts +14 -0
- package/dist/typescript/module/specs/NativeRNBootSplash.d.ts.map +1 -0
- package/dist/typescript/module/specs/NativeRNBootSplash.web.d.ts +9 -0
- package/dist/typescript/module/specs/NativeRNBootSplash.web.d.ts.map +1 -0
- package/package.json +49 -19
- package/src/{expo.ts → extras/expo.ts} +31 -40
- package/src/extras/generate.ts +410 -0
- package/src/{generate.ts → extras/utils.ts} +180 -494
- package/dist/commonjs/addon/index.js +0 -97
- package/dist/commonjs/addon/index.js.map +0 -1
- package/dist/commonjs/expo.js.map +0 -1
- package/dist/commonjs/generate.js.map +0 -1
- package/dist/module/addon/index.js +0 -97
- package/dist/module/addon/index.js.map +0 -1
- package/dist/module/expo.js.map +0 -1
- package/dist/module/generate.js.map +0 -1
- package/dist/typescript/addon/index.d.ts.map +0 -1
- package/dist/typescript/expo.d.ts +0 -6
- package/dist/typescript/expo.d.ts.map +0 -1
- package/dist/typescript/generate.d.ts.map +0 -1
- package/dist/typescript/index.d.ts.map +0 -1
- package/dist/typescript/specs/NativeRNBootSplash.d.ts.map +0 -1
- package/dist/typescript/specs/NativeRNBootSplash.web.d.ts.map +0 -1
- /package/dist/typescript/{index.d.ts → commonjs/index.d.ts} +0 -0
- /package/dist/typescript/{specs → commonjs/specs}/NativeRNBootSplash.d.ts +0 -0
- /package/dist/typescript/{specs → commonjs/specs}/NativeRNBootSplash.web.d.ts +0 -0
|
@@ -8,32 +8,33 @@ import semver from "semver";
|
|
|
8
8
|
import { dedent } from "ts-dedent";
|
|
9
9
|
import util from "util";
|
|
10
10
|
import {
|
|
11
|
-
type
|
|
11
|
+
type BootSplashPluginConfig,
|
|
12
12
|
hfs,
|
|
13
13
|
log,
|
|
14
14
|
PACKAGE_NAME,
|
|
15
15
|
requireAddon,
|
|
16
|
-
|
|
16
|
+
setLoggerMode,
|
|
17
17
|
transformProps,
|
|
18
18
|
writeAndroidAssets,
|
|
19
19
|
writeGenericAssets,
|
|
20
20
|
writeIOSAssets,
|
|
21
21
|
writeWebAssets,
|
|
22
|
-
} from "./
|
|
22
|
+
} from "./utils";
|
|
23
23
|
|
|
24
24
|
const promisifiedExec = util.promisify(childProcess.exec);
|
|
25
25
|
|
|
26
26
|
const exec = (cmd: string) =>
|
|
27
27
|
promisifiedExec(cmd).then(({ stdout, stderr }) => stdout || stderr);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
type ConfigPlugin = Expo.ConfigPlugin<BootSplashPluginConfig>;
|
|
30
|
+
|
|
31
|
+
const withoutExpoSplashScreen: ConfigPlugin = Expo.createRunOncePlugin(
|
|
32
|
+
(expoConfig) => expoConfig,
|
|
33
|
+
"expo-splash-screen",
|
|
34
|
+
"skip",
|
|
35
|
+
);
|
|
35
36
|
|
|
36
|
-
const withAndroidAssets:
|
|
37
|
+
const withAndroidAssets: ConfigPlugin = (expoConfig, rawProps) =>
|
|
37
38
|
Expo.withDangerousMod(expoConfig, [
|
|
38
39
|
"android",
|
|
39
40
|
async (config) => {
|
|
@@ -56,7 +57,7 @@ const withAndroidAssets: Expo.ConfigPlugin<RawProps> = (expoConfig, rawProps) =>
|
|
|
56
57
|
},
|
|
57
58
|
]);
|
|
58
59
|
|
|
59
|
-
const withAndroidManifest:
|
|
60
|
+
const withAndroidManifest: ConfigPlugin = (expoConfig) =>
|
|
60
61
|
Expo.withAndroidManifest(expoConfig, (config) => {
|
|
61
62
|
config.modResults.manifest.application?.forEach((application) => {
|
|
62
63
|
if (application.$["android:name"] === ".MainApplication") {
|
|
@@ -73,7 +74,7 @@ const withAndroidManifest: Expo.ConfigPlugin<RawProps> = (expoConfig) =>
|
|
|
73
74
|
return config;
|
|
74
75
|
});
|
|
75
76
|
|
|
76
|
-
const withMainActivity:
|
|
77
|
+
const withMainActivity: ConfigPlugin = (expoConfig) =>
|
|
77
78
|
Expo.withMainActivity(expoConfig, (config) => {
|
|
78
79
|
const { modResults } = config;
|
|
79
80
|
|
|
@@ -105,7 +106,7 @@ const withMainActivity: Expo.ConfigPlugin<RawProps> = (expoConfig) =>
|
|
|
105
106
|
};
|
|
106
107
|
});
|
|
107
108
|
|
|
108
|
-
const withAndroidStyles:
|
|
109
|
+
const withAndroidStyles: ConfigPlugin = (expoConfig, rawProps) =>
|
|
109
110
|
Expo.withAndroidStyles(expoConfig, async (config) => {
|
|
110
111
|
const { projectRoot } = config.modRequest;
|
|
111
112
|
const { android, brand } = await transformProps(projectRoot, rawProps);
|
|
@@ -166,7 +167,7 @@ const withAndroidStyles: Expo.ConfigPlugin<RawProps> = (expoConfig, rawProps) =>
|
|
|
166
167
|
};
|
|
167
168
|
});
|
|
168
169
|
|
|
169
|
-
const withAndroidColors:
|
|
170
|
+
const withAndroidColors: ConfigPlugin = (expoConfig, rawProps) =>
|
|
170
171
|
Expo.withAndroidColors(expoConfig, async (config) => {
|
|
171
172
|
const { projectRoot } = config.modRequest;
|
|
172
173
|
const { background } = await transformProps(projectRoot, rawProps);
|
|
@@ -179,10 +180,7 @@ const withAndroidColors: Expo.ConfigPlugin<RawProps> = (expoConfig, rawProps) =>
|
|
|
179
180
|
return config;
|
|
180
181
|
});
|
|
181
182
|
|
|
182
|
-
const withAndroidColorsNight:
|
|
183
|
-
expoConfig,
|
|
184
|
-
rawProps,
|
|
185
|
-
) =>
|
|
183
|
+
const withAndroidColorsNight: ConfigPlugin = (expoConfig, rawProps) =>
|
|
186
184
|
Expo.withAndroidColorsNight(expoConfig, async (config) => {
|
|
187
185
|
const { projectRoot } = config.modRequest;
|
|
188
186
|
const props = await transformProps(projectRoot, rawProps);
|
|
@@ -193,7 +191,7 @@ const withAndroidColorsNight: Expo.ConfigPlugin<RawProps> = (
|
|
|
193
191
|
: config;
|
|
194
192
|
});
|
|
195
193
|
|
|
196
|
-
const withIOSAssets:
|
|
194
|
+
const withIOSAssets: ConfigPlugin = (expoConfig, rawProps) =>
|
|
197
195
|
Expo.withDangerousMod(expoConfig, [
|
|
198
196
|
"ios",
|
|
199
197
|
async (config) => {
|
|
@@ -214,7 +212,7 @@ const withIOSAssets: Expo.ConfigPlugin<RawProps> = (expoConfig, rawProps) =>
|
|
|
214
212
|
},
|
|
215
213
|
]);
|
|
216
214
|
|
|
217
|
-
const withAppDelegate:
|
|
215
|
+
const withAppDelegate: ConfigPlugin = (expoConfig) =>
|
|
218
216
|
Expo.withAppDelegate(expoConfig, (config) => {
|
|
219
217
|
const { modResults } = config;
|
|
220
218
|
const { language } = modResults;
|
|
@@ -257,13 +255,13 @@ const withAppDelegate: Expo.ConfigPlugin<RawProps> = (expoConfig) =>
|
|
|
257
255
|
};
|
|
258
256
|
});
|
|
259
257
|
|
|
260
|
-
const withInfoPlist:
|
|
258
|
+
const withInfoPlist: ConfigPlugin = (expoConfig) =>
|
|
261
259
|
Expo.withInfoPlist(expoConfig, (config) => {
|
|
262
260
|
config.modResults["UILaunchStoryboardName"] = "BootSplash";
|
|
263
261
|
return config;
|
|
264
262
|
});
|
|
265
263
|
|
|
266
|
-
const withXcodeProject:
|
|
264
|
+
const withXcodeProject: ConfigPlugin = (expoConfig) =>
|
|
267
265
|
Expo.withXcodeProject(expoConfig, (config) => {
|
|
268
266
|
const { projectName = "" } = config.modRequest;
|
|
269
267
|
|
|
@@ -284,7 +282,7 @@ const withXcodeProject: Expo.ConfigPlugin<RawProps> = (expoConfig) =>
|
|
|
284
282
|
return config;
|
|
285
283
|
});
|
|
286
284
|
|
|
287
|
-
const withWebAssets:
|
|
285
|
+
const withWebAssets: ConfigPlugin = (expoConfig, rawProps) =>
|
|
288
286
|
Expo.withDangerousMod(expoConfig, [
|
|
289
287
|
expoConfig.platforms?.includes("ios") ? "ios" : "android",
|
|
290
288
|
async (config) => {
|
|
@@ -306,7 +304,7 @@ const withWebAssets: Expo.ConfigPlugin<RawProps> = (expoConfig, rawProps) =>
|
|
|
306
304
|
},
|
|
307
305
|
]);
|
|
308
306
|
|
|
309
|
-
const withGenericAssets:
|
|
307
|
+
const withGenericAssets: ConfigPlugin = (expoConfig, rawProps) =>
|
|
310
308
|
Expo.withDangerousMod(expoConfig, [
|
|
311
309
|
expoConfig.platforms?.includes("ios") ? "ios" : "android",
|
|
312
310
|
async (config) => {
|
|
@@ -322,34 +320,23 @@ const withGenericAssets: Expo.ConfigPlugin<RawProps> = (expoConfig, rawProps) =>
|
|
|
322
320
|
]);
|
|
323
321
|
|
|
324
322
|
export const withBootSplash = Expo.createRunOncePlugin<
|
|
325
|
-
(Partial<
|
|
326
|
-
>((expoConfig,
|
|
323
|
+
(Partial<BootSplashPluginConfig> & { logo: string }) | undefined
|
|
324
|
+
>((expoConfig, rawProps) => {
|
|
327
325
|
const { platforms = [], sdkVersion = "0.1.0" } = expoConfig;
|
|
328
326
|
|
|
329
|
-
|
|
327
|
+
setLoggerMode({ type: "plugin" });
|
|
330
328
|
|
|
331
329
|
if (semver.lt(sdkVersion, "54.0.0")) {
|
|
332
330
|
log.error("Requires Expo 54.0.0 (or higher)");
|
|
333
331
|
process.exit(1);
|
|
334
332
|
}
|
|
335
333
|
|
|
336
|
-
if (!
|
|
334
|
+
if (!rawProps?.logo) {
|
|
337
335
|
log.error("Missing required parameter 'logo'");
|
|
338
336
|
process.exit(1);
|
|
339
337
|
}
|
|
340
338
|
|
|
341
|
-
const
|
|
342
|
-
assetsOutput: "assets/bootsplash",
|
|
343
|
-
background: "#fff",
|
|
344
|
-
brandWidth: 80,
|
|
345
|
-
logoWidth: 100,
|
|
346
|
-
...baseProps,
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
const plugins: Expo.ConfigPlugin<RawProps>[] = [
|
|
350
|
-
withoutExpoSplashScreen,
|
|
351
|
-
withGenericAssets,
|
|
352
|
-
];
|
|
339
|
+
const plugins: ConfigPlugin[] = [withoutExpoSplashScreen, withGenericAssets];
|
|
353
340
|
|
|
354
341
|
if (platforms.includes("android")) {
|
|
355
342
|
plugins.push(
|
|
@@ -380,3 +367,7 @@ export const withBootSplash = Expo.createRunOncePlugin<
|
|
|
380
367
|
plugins.map((plugin) => [plugin, rawProps]),
|
|
381
368
|
);
|
|
382
369
|
}, PACKAGE_NAME);
|
|
370
|
+
|
|
371
|
+
export default (
|
|
372
|
+
config: BootSplashPluginConfig,
|
|
373
|
+
): [typeof PACKAGE_NAME, BootSplashPluginConfig] => [PACKAGE_NAME, config];
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import * as Expo from "@expo/config-plugins";
|
|
2
|
+
import ExpoPlist from "@expo/plist";
|
|
3
|
+
import glob from "fast-glob";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import { HTMLElement, parse as parseHtml } from "node-html-parser";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import pc from "picocolors";
|
|
8
|
+
import { dedent } from "ts-dedent";
|
|
9
|
+
import formatXml from "xml-formatter";
|
|
10
|
+
import {
|
|
11
|
+
hfs,
|
|
12
|
+
log,
|
|
13
|
+
readXmlLike,
|
|
14
|
+
requireAddon,
|
|
15
|
+
setLoggerMode,
|
|
16
|
+
transformProps,
|
|
17
|
+
writeAndroidAssets,
|
|
18
|
+
writeGenericAssets,
|
|
19
|
+
writeIOSAssets,
|
|
20
|
+
writeWebAssets,
|
|
21
|
+
writeXmlLike,
|
|
22
|
+
} from "./utils";
|
|
23
|
+
|
|
24
|
+
const cwd = process.env.INIT_CWD ?? process.env.PWD ?? process.cwd();
|
|
25
|
+
setLoggerMode({ type: "cli", cwd });
|
|
26
|
+
|
|
27
|
+
const projectRoot = (() => {
|
|
28
|
+
let directory = path.resolve(cwd);
|
|
29
|
+
|
|
30
|
+
const { root } = path.parse(directory);
|
|
31
|
+
const ends = new Set([root, path.resolve(directory, root)]);
|
|
32
|
+
|
|
33
|
+
while (directory) {
|
|
34
|
+
const pkgPath = path.join(directory, "package.json");
|
|
35
|
+
const stats = fs.statSync(pkgPath, { throwIfNoEntry: false });
|
|
36
|
+
|
|
37
|
+
if (stats != null && stats.isFile()) {
|
|
38
|
+
return path.dirname(pkgPath);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (ends.has(directory)) {
|
|
42
|
+
break;
|
|
43
|
+
} else {
|
|
44
|
+
directory = path.dirname(directory);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
})();
|
|
48
|
+
|
|
49
|
+
if (!projectRoot) {
|
|
50
|
+
log.error("We couldn't find a package.json in your project.");
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const getAndroidOutputPath = ({ flavor }: { flavor: string }) => {
|
|
55
|
+
const sourceDir = path.join(projectRoot, "android");
|
|
56
|
+
|
|
57
|
+
if (!fs.existsSync(sourceDir)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const appDir = path.join(sourceDir, "app");
|
|
62
|
+
|
|
63
|
+
const androidOutputPath = path.resolve(
|
|
64
|
+
sourceDir,
|
|
65
|
+
fs.existsSync(appDir) ? "app" : "",
|
|
66
|
+
"src",
|
|
67
|
+
flavor,
|
|
68
|
+
"res",
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (hfs.exists(androidOutputPath)) {
|
|
72
|
+
return androidOutputPath;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
log.warn(
|
|
76
|
+
`No ${path.relative(
|
|
77
|
+
cwd,
|
|
78
|
+
androidOutputPath,
|
|
79
|
+
)} directory found. Skipping Android assets generation…`,
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const getIOSOutputPath = () => {
|
|
84
|
+
const podfile = glob
|
|
85
|
+
.sync("**/Podfile", {
|
|
86
|
+
cwd: projectRoot.replace(/^([a-zA-Z]+:|\.\/)/, ""),
|
|
87
|
+
deep: 10,
|
|
88
|
+
ignore: ["**/@(Pods|node_modules|Carthage|vendor|android)/**"],
|
|
89
|
+
})
|
|
90
|
+
.find((project) => {
|
|
91
|
+
return path.dirname(project) === "ios";
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (!podfile) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const sourceDir = path.dirname(path.join(projectRoot, podfile));
|
|
99
|
+
|
|
100
|
+
const xcodeProjectName = fs
|
|
101
|
+
.readdirSync(sourceDir)
|
|
102
|
+
.sort()
|
|
103
|
+
.reverse()
|
|
104
|
+
.find((fileName) => {
|
|
105
|
+
const ext = path.extname(fileName);
|
|
106
|
+
return ext === ".xcodeproj" || ext === ".xcworkspace";
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (xcodeProjectName == null) {
|
|
110
|
+
log.warn("No Xcode project found. Skipping iOS assets generation…");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const iosOutputPath = path
|
|
115
|
+
.resolve(sourceDir, xcodeProjectName)
|
|
116
|
+
.replace(/\.(xcodeproj|xcworkspace)$/, "");
|
|
117
|
+
|
|
118
|
+
if (hfs.exists(iosOutputPath)) {
|
|
119
|
+
return iosOutputPath;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
log.warn(
|
|
123
|
+
`No ${path.relative(
|
|
124
|
+
cwd,
|
|
125
|
+
iosOutputPath,
|
|
126
|
+
)} directory found. Skipping iOS assets generation…`,
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const getHtmlTemplatePath = ({ html }: { html: string }) => {
|
|
131
|
+
const htmlTemplatePath = path.resolve(cwd, html);
|
|
132
|
+
|
|
133
|
+
if (hfs.exists(htmlTemplatePath)) {
|
|
134
|
+
return htmlTemplatePath;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
log.warn(
|
|
138
|
+
`No ${path.relative(
|
|
139
|
+
cwd,
|
|
140
|
+
htmlTemplatePath,
|
|
141
|
+
)} found. Skipping HTML + CSS generation…`,
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const getInfoPlistPath = ({
|
|
146
|
+
iosOutputPath,
|
|
147
|
+
plist,
|
|
148
|
+
}: {
|
|
149
|
+
iosOutputPath: string;
|
|
150
|
+
plist: string | undefined;
|
|
151
|
+
}) => {
|
|
152
|
+
if (plist != null) {
|
|
153
|
+
const infoPlistPath = path.resolve(cwd, plist);
|
|
154
|
+
|
|
155
|
+
if (!hfs.exists(infoPlistPath)) {
|
|
156
|
+
return log.warn(`No ${path.relative(cwd, infoPlistPath)} found`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return infoPlistPath;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return path.resolve(iosOutputPath, "Info.plist");
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const generate = async ({
|
|
166
|
+
platforms,
|
|
167
|
+
html,
|
|
168
|
+
flavor,
|
|
169
|
+
plist,
|
|
170
|
+
...rawProps
|
|
171
|
+
}: {
|
|
172
|
+
platforms: Array<"android" | "ios" | "web">;
|
|
173
|
+
html: string;
|
|
174
|
+
flavor: string;
|
|
175
|
+
plist?: string;
|
|
176
|
+
|
|
177
|
+
logo: string;
|
|
178
|
+
background: string;
|
|
179
|
+
logoWidth: number;
|
|
180
|
+
assetsOutput: string;
|
|
181
|
+
licenseKey?: string;
|
|
182
|
+
brand?: string;
|
|
183
|
+
brandWidth: number;
|
|
184
|
+
darkBackground?: string;
|
|
185
|
+
darkLogo?: string;
|
|
186
|
+
darkBrand?: string;
|
|
187
|
+
}) => {
|
|
188
|
+
const props = await transformProps(cwd, rawProps);
|
|
189
|
+
const addon = requireAddon(props);
|
|
190
|
+
|
|
191
|
+
const { background, brand } = props;
|
|
192
|
+
|
|
193
|
+
const androidOutputPath = platforms.includes("android")
|
|
194
|
+
? getAndroidOutputPath({ flavor })
|
|
195
|
+
: undefined;
|
|
196
|
+
|
|
197
|
+
const iosOutputPath = platforms.includes("ios")
|
|
198
|
+
? getIOSOutputPath()
|
|
199
|
+
: undefined;
|
|
200
|
+
|
|
201
|
+
const htmlTemplatePath = platforms.includes("web")
|
|
202
|
+
? getHtmlTemplatePath({ html })
|
|
203
|
+
: undefined;
|
|
204
|
+
|
|
205
|
+
if (androidOutputPath != null) {
|
|
206
|
+
await writeAndroidAssets({ androidOutputPath, props });
|
|
207
|
+
|
|
208
|
+
const manifestXmlPath = path.resolve(
|
|
209
|
+
androidOutputPath,
|
|
210
|
+
"..",
|
|
211
|
+
"AndroidManifest.xml",
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (hfs.exists(manifestXmlPath)) {
|
|
215
|
+
const manifestXml = readXmlLike(manifestXmlPath);
|
|
216
|
+
const activities = manifestXml.root.querySelectorAll("activity");
|
|
217
|
+
|
|
218
|
+
for (const activity of activities) {
|
|
219
|
+
if (activity.getAttribute("android:name") === ".MainActivity") {
|
|
220
|
+
activity.setAttribute("android:theme", "@style/BootTheme");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
await writeXmlLike(manifestXmlPath, manifestXml.root.toString(), {
|
|
225
|
+
...manifestXml.formatOptions,
|
|
226
|
+
formatter: "prettier",
|
|
227
|
+
htmlWhitespaceSensitivity: "ignore",
|
|
228
|
+
selfClosingTags: true,
|
|
229
|
+
singleAttributePerLine: true,
|
|
230
|
+
});
|
|
231
|
+
} else {
|
|
232
|
+
log.warn("No AndroidManifest.xml found");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const valuesPath = path.resolve(androidOutputPath, "values");
|
|
236
|
+
hfs.ensureDir(valuesPath);
|
|
237
|
+
|
|
238
|
+
const colorsXmlPath = path.resolve(valuesPath, "colors.xml");
|
|
239
|
+
const colorsXmlEntry = `<color name="bootsplash_background">${background.hex}</color>`;
|
|
240
|
+
|
|
241
|
+
if (hfs.exists(colorsXmlPath)) {
|
|
242
|
+
const colorsXml = readXmlLike(colorsXmlPath);
|
|
243
|
+
const nextColor = parseHtml(colorsXmlEntry);
|
|
244
|
+
|
|
245
|
+
const prevColor = colorsXml.root.querySelector(
|
|
246
|
+
'color[name="bootsplash_background"]',
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
if (prevColor != null) {
|
|
250
|
+
prevColor.replaceWith(nextColor);
|
|
251
|
+
} else {
|
|
252
|
+
colorsXml.root.querySelector("resources")?.appendChild(nextColor);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
await writeXmlLike(colorsXmlPath, colorsXml.root.toString(), {
|
|
256
|
+
...colorsXml.formatOptions,
|
|
257
|
+
formatter: "xmlFormatter",
|
|
258
|
+
});
|
|
259
|
+
} else {
|
|
260
|
+
await writeXmlLike(
|
|
261
|
+
colorsXmlPath,
|
|
262
|
+
`<resources>${colorsXmlEntry}</resources>`,
|
|
263
|
+
{ formatter: "xmlFormatter" },
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const stylesXmlPath = path.resolve(valuesPath, "styles.xml");
|
|
268
|
+
|
|
269
|
+
if (hfs.exists(stylesXmlPath)) {
|
|
270
|
+
const stylesXml = readXmlLike(stylesXmlPath);
|
|
271
|
+
const prevStyle = stylesXml.root.querySelector('style[name="BootTheme"]');
|
|
272
|
+
const parent = prevStyle?.getAttribute("parent") ?? "Theme.BootSplash";
|
|
273
|
+
|
|
274
|
+
const extraItems = parseHtml(
|
|
275
|
+
prevStyle?.text
|
|
276
|
+
.split("\n")
|
|
277
|
+
.map((line) => line.trim())
|
|
278
|
+
.join("") ?? "",
|
|
279
|
+
)
|
|
280
|
+
.childNodes.filter((node) => {
|
|
281
|
+
if (!(node instanceof HTMLElement)) {
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const name = node.getAttribute("name");
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
name !== "bootSplashBackground" &&
|
|
289
|
+
name !== "bootSplashLogo" &&
|
|
290
|
+
name !== "bootSplashBrand" &&
|
|
291
|
+
name !== "postBootSplashTheme"
|
|
292
|
+
);
|
|
293
|
+
})
|
|
294
|
+
.map((node) => node.toString());
|
|
295
|
+
|
|
296
|
+
const styleItems: string[] = [
|
|
297
|
+
...(extraItems.length > 0 ? [...extraItems, ""] : []),
|
|
298
|
+
|
|
299
|
+
'<item name="bootSplashBackground">@color/bootsplash_background</item>',
|
|
300
|
+
'<item name="bootSplashLogo">@drawable/bootsplash_logo</item>',
|
|
301
|
+
|
|
302
|
+
...(brand != null
|
|
303
|
+
? ['<item name="bootSplashBrand">@drawable/bootsplash_brand</item>']
|
|
304
|
+
: []),
|
|
305
|
+
|
|
306
|
+
'<item name="postBootSplashTheme">@style/AppTheme</item>',
|
|
307
|
+
];
|
|
308
|
+
|
|
309
|
+
const nextStyle = parseHtml(dedent`
|
|
310
|
+
<style name="BootTheme" parent="${parent}">
|
|
311
|
+
${styleItems.join("\n")}
|
|
312
|
+
</style>
|
|
313
|
+
`);
|
|
314
|
+
|
|
315
|
+
prevStyle?.remove(); // remove the existing style
|
|
316
|
+
stylesXml.root.querySelector("resources")?.appendChild(nextStyle);
|
|
317
|
+
|
|
318
|
+
await writeXmlLike(stylesXmlPath, stylesXml.root.toString(), {
|
|
319
|
+
...stylesXml.formatOptions,
|
|
320
|
+
formatter: "prettier",
|
|
321
|
+
htmlWhitespaceSensitivity: "ignore",
|
|
322
|
+
});
|
|
323
|
+
} else {
|
|
324
|
+
log.warn("No styles.xml found");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (iosOutputPath != null) {
|
|
329
|
+
await writeIOSAssets({ iosOutputPath, props });
|
|
330
|
+
|
|
331
|
+
const pbxprojectPath = Expo.IOSConfig.Paths.getPBXProjectPath(projectRoot);
|
|
332
|
+
|
|
333
|
+
const xcodeProjectPath =
|
|
334
|
+
Expo.IOSConfig.Paths.getXcodeProjectPath(projectRoot);
|
|
335
|
+
|
|
336
|
+
const project = Expo.IOSConfig.XcodeUtils.getPbxproj(projectRoot);
|
|
337
|
+
const projectName = path.basename(iosOutputPath);
|
|
338
|
+
const groupName = path.parse(xcodeProjectPath).name;
|
|
339
|
+
|
|
340
|
+
Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
|
|
341
|
+
project,
|
|
342
|
+
filepath: path.join(projectName, "BootSplash.storyboard"),
|
|
343
|
+
groupName,
|
|
344
|
+
isBuildFile: true,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
|
|
348
|
+
project,
|
|
349
|
+
filepath: path.join(projectName, "Colors.xcassets"),
|
|
350
|
+
groupName,
|
|
351
|
+
isBuildFile: true,
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
hfs.write(pbxprojectPath, project.writeSync());
|
|
355
|
+
log.write(pbxprojectPath);
|
|
356
|
+
|
|
357
|
+
const infoPlistPath = getInfoPlistPath({ iosOutputPath, plist });
|
|
358
|
+
|
|
359
|
+
if (infoPlistPath != null) {
|
|
360
|
+
const infoPlist = ExpoPlist.parse(hfs.text(infoPlistPath)) as Record<
|
|
361
|
+
string,
|
|
362
|
+
unknown
|
|
363
|
+
>;
|
|
364
|
+
|
|
365
|
+
infoPlist["UILaunchStoryboardName"] = "BootSplash";
|
|
366
|
+
|
|
367
|
+
const formatted = formatXml(ExpoPlist.build(infoPlist), {
|
|
368
|
+
collapseContent: true,
|
|
369
|
+
forceSelfClosingEmptyTag: false,
|
|
370
|
+
indentation: "\t",
|
|
371
|
+
lineSeparator: "\n",
|
|
372
|
+
whiteSpaceAtEndOfSelfclosingTag: false,
|
|
373
|
+
})
|
|
374
|
+
.replace(/<string\/>/gm, "<string></string>")
|
|
375
|
+
.replace(/^\t/gm, "");
|
|
376
|
+
|
|
377
|
+
hfs.write(infoPlistPath, formatted);
|
|
378
|
+
log.write(infoPlistPath);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (htmlTemplatePath != null) {
|
|
383
|
+
await writeWebAssets({ htmlTemplatePath, props });
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
await writeGenericAssets({ props });
|
|
387
|
+
|
|
388
|
+
if (addon != null) {
|
|
389
|
+
await addon.execute({
|
|
390
|
+
props,
|
|
391
|
+
androidOutputPath,
|
|
392
|
+
iosOutputPath,
|
|
393
|
+
htmlTemplatePath,
|
|
394
|
+
});
|
|
395
|
+
} else {
|
|
396
|
+
console.log(`
|
|
397
|
+
${pc.blue("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")}
|
|
398
|
+
${pc.blue("┃")} 🔑 ${pc.bold(
|
|
399
|
+
"Get a license key for brand image / dark mode support",
|
|
400
|
+
)} ${pc.blue("┃")}
|
|
401
|
+
${pc.blue("┃")} ${pc.underline(
|
|
402
|
+
"https://zoontek.gumroad.com/l/bootsplash-generator",
|
|
403
|
+
)} ${pc.blue("┃")}
|
|
404
|
+
${pc.blue("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")}`);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
console.log(
|
|
408
|
+
`\n💖 Thanks for using ${pc.underline("react-native-bootsplash")}`,
|
|
409
|
+
);
|
|
410
|
+
};
|