react-native-bootsplash 5.3.0 → 5.4.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/README.md +3 -13
- package/dist/commonjs/addon/index.js +29 -29
- package/dist/commonjs/addon/index.js.map +1 -1
- package/dist/commonjs/generate.js +74 -30
- package/dist/commonjs/generate.js.map +1 -1
- package/dist/module/addon/index.js +29 -29
- package/dist/module/addon/index.js.map +1 -1
- package/dist/module/generate.js +72 -29
- package/dist/module/generate.js.map +1 -1
- package/dist/typescript/addon/index.d.ts.map +1 -1
- package/dist/typescript/generate.d.ts +25 -9
- package/dist/typescript/generate.d.ts.map +1 -1
- package/package.json +2 -4
- package/react-native.config.js +2 -2
- package/src/generate.ts +99 -30
package/src/generate.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import murmurhash from "@emotion/hash";
|
|
2
|
+
import { IOSConfig } from "@expo/config-plugins";
|
|
3
|
+
import plist from "@expo/plist";
|
|
4
|
+
import { findProjectRoot } from "@react-native-community/cli-tools";
|
|
2
5
|
import {
|
|
3
6
|
AndroidProjectConfig,
|
|
4
|
-
CommandFunction,
|
|
5
7
|
IOSProjectConfig,
|
|
6
8
|
} from "@react-native-community/cli-types";
|
|
7
9
|
import detectIndent from "detect-indent";
|
|
8
|
-
import fs from "fs
|
|
10
|
+
import fs from "fs";
|
|
9
11
|
import { parse as parseHtml } from "node-html-parser";
|
|
10
12
|
import path from "path";
|
|
11
13
|
import pc from "picocolors";
|
|
@@ -103,6 +105,43 @@ const getStoryboard = ({
|
|
|
103
105
|
`;
|
|
104
106
|
};
|
|
105
107
|
|
|
108
|
+
export const addFileToXcodeProject = (filePath: string) => {
|
|
109
|
+
const projectRoot = findProjectRoot(workingPath);
|
|
110
|
+
|
|
111
|
+
const pbxprojectPath = IOSConfig.Paths.getPBXProjectPath(projectRoot);
|
|
112
|
+
const project = IOSConfig.XcodeUtils.getPbxproj(projectRoot);
|
|
113
|
+
const xcodeProjectPath = IOSConfig.Paths.getXcodeProjectPath(projectRoot);
|
|
114
|
+
|
|
115
|
+
IOSConfig.XcodeUtils.addResourceFileToGroup({
|
|
116
|
+
filepath: filePath,
|
|
117
|
+
groupName: path.parse(xcodeProjectPath).name,
|
|
118
|
+
project,
|
|
119
|
+
isBuildFile: true,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
hfs.write(pbxprojectPath, project.writeSync());
|
|
123
|
+
logWrite(pbxprojectPath);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Freely inspired by https://github.com/humanwhocodes/humanfs
|
|
127
|
+
export const hfs = {
|
|
128
|
+
buffer: (path: string) => fs.readFileSync(path),
|
|
129
|
+
exists: (path: string) => fs.existsSync(path),
|
|
130
|
+
json: (path: string) => JSON.parse(fs.readFileSync(path, "utf-8")) as unknown,
|
|
131
|
+
readDir: (path: string) => fs.readdirSync(path, "utf-8"),
|
|
132
|
+
realPath: (path: string) => fs.realpathSync(path, "utf-8"),
|
|
133
|
+
rm: (path: string) => fs.rmSync(path, { force: true }),
|
|
134
|
+
text: (path: string) => fs.readFileSync(path, "utf-8"),
|
|
135
|
+
|
|
136
|
+
ensureDir: (dir: string) => {
|
|
137
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
138
|
+
},
|
|
139
|
+
write: (file: string, data: string) => {
|
|
140
|
+
const trimmed = data.trim();
|
|
141
|
+
fs.writeFileSync(file, trimmed === "" ? trimmed : trimmed + "\n", "utf-8");
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
106
145
|
export const log = {
|
|
107
146
|
error: (text: string) => console.log(pc.red(`❌ ${text}`)),
|
|
108
147
|
text: (text: string) => console.log(text),
|
|
@@ -121,12 +160,12 @@ export const logWrite = (
|
|
|
121
160
|
);
|
|
122
161
|
|
|
123
162
|
export const writeJson = (file: string, json: object) => {
|
|
124
|
-
|
|
163
|
+
hfs.write(file, JSON.stringify(json, null, 2));
|
|
125
164
|
logWrite(file);
|
|
126
165
|
};
|
|
127
166
|
|
|
128
167
|
export const readXml = (file: string) => {
|
|
129
|
-
const xml =
|
|
168
|
+
const xml = hfs.text(file);
|
|
130
169
|
const { indent } = detectIndent(xml);
|
|
131
170
|
|
|
132
171
|
const formatOptions: XMLFormatterOptions = {
|
|
@@ -150,12 +189,12 @@ export const writeXml = (
|
|
|
150
189
|
...options,
|
|
151
190
|
});
|
|
152
191
|
|
|
153
|
-
|
|
192
|
+
hfs.write(file, formatted);
|
|
154
193
|
logWrite(file);
|
|
155
194
|
};
|
|
156
195
|
|
|
157
196
|
export const readHtml = (file: string) => {
|
|
158
|
-
const html =
|
|
197
|
+
const html = hfs.text(file);
|
|
159
198
|
const { type, amount } = detectIndent(html);
|
|
160
199
|
|
|
161
200
|
const formatOptions: PrettierOptions = {
|
|
@@ -179,15 +218,16 @@ export const writeHtml = async (
|
|
|
179
218
|
...options,
|
|
180
219
|
});
|
|
181
220
|
|
|
182
|
-
|
|
221
|
+
hfs.write(file, formatted);
|
|
183
222
|
logWrite(file);
|
|
184
223
|
};
|
|
185
224
|
|
|
186
225
|
export const cleanIOSAssets = (dir: string, prefix: string) => {
|
|
187
|
-
|
|
226
|
+
hfs
|
|
227
|
+
.readDir(dir)
|
|
188
228
|
.filter((file) => file.startsWith(prefix) && file.endsWith(".png"))
|
|
189
229
|
.map((file) => path.join(dir, file))
|
|
190
|
-
.forEach((file) =>
|
|
230
|
+
.forEach((file) => hfs.rm(file));
|
|
191
231
|
};
|
|
192
232
|
|
|
193
233
|
export const getIOSAssetFileName = async ({
|
|
@@ -249,7 +289,7 @@ const getAndroidResPath = (
|
|
|
249
289
|
"res",
|
|
250
290
|
);
|
|
251
291
|
|
|
252
|
-
if (!
|
|
292
|
+
if (!hfs.exists(androidResPath)) {
|
|
253
293
|
log.warn(
|
|
254
294
|
`No ${path.relative(
|
|
255
295
|
workingPath,
|
|
@@ -283,7 +323,7 @@ const getIOSProjectPath = (ios: IOSProjectConfig): string | undefined => {
|
|
|
283
323
|
.resolve(ios.sourceDir, ios.xcodeProject.name)
|
|
284
324
|
.replace(/\.(xcodeproj|xcworkspace)$/, "");
|
|
285
325
|
|
|
286
|
-
if (!
|
|
326
|
+
if (!hfs.exists(iosProjectPath)) {
|
|
287
327
|
log.warn(
|
|
288
328
|
`No ${path.relative(
|
|
289
329
|
workingPath,
|
|
@@ -298,7 +338,7 @@ const getIOSProjectPath = (ios: IOSProjectConfig): string | undefined => {
|
|
|
298
338
|
const getHtmlTemplatePath = (html: string): string | undefined => {
|
|
299
339
|
const htmlTemplatePath = path.resolve(workingPath, html);
|
|
300
340
|
|
|
301
|
-
if (!
|
|
341
|
+
if (!hfs.exists(htmlTemplatePath)) {
|
|
302
342
|
log.warn(
|
|
303
343
|
`No ${path.relative(
|
|
304
344
|
workingPath,
|
|
@@ -347,7 +387,19 @@ const requireAddon = ():
|
|
|
347
387
|
}
|
|
348
388
|
};
|
|
349
389
|
|
|
350
|
-
export const generate
|
|
390
|
+
export const generate = async ({
|
|
391
|
+
android,
|
|
392
|
+
ios,
|
|
393
|
+
platforms,
|
|
394
|
+
html,
|
|
395
|
+
flavor,
|
|
396
|
+
licenseKey,
|
|
397
|
+
...args
|
|
398
|
+
}: {
|
|
399
|
+
android?: AndroidProjectConfig;
|
|
400
|
+
ios?: IOSProjectConfig;
|
|
401
|
+
|
|
402
|
+
logo: string;
|
|
351
403
|
platforms: string[];
|
|
352
404
|
background: string;
|
|
353
405
|
logoWidth: number;
|
|
@@ -361,11 +413,7 @@ export const generate: CommandFunction<{
|
|
|
361
413
|
darkBackground?: string;
|
|
362
414
|
darkLogo?: string;
|
|
363
415
|
darkBrand?: string;
|
|
364
|
-
}
|
|
365
|
-
[argsLogo],
|
|
366
|
-
{ project: { android, ios } },
|
|
367
|
-
{ platforms, html, flavor, licenseKey, ...args },
|
|
368
|
-
) => {
|
|
416
|
+
}) => {
|
|
369
417
|
const [nodeStringVersion = ""] = process.versions.node.split(".");
|
|
370
418
|
const nodeVersion = parseInt(nodeStringVersion, 10);
|
|
371
419
|
|
|
@@ -374,12 +422,7 @@ export const generate: CommandFunction<{
|
|
|
374
422
|
process.exit(1);
|
|
375
423
|
}
|
|
376
424
|
|
|
377
|
-
|
|
378
|
-
log.error("Missing required argument 'logo'");
|
|
379
|
-
process.exit(1);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const logoPath = path.resolve(workingPath, argsLogo);
|
|
425
|
+
const logoPath = path.resolve(workingPath, args.logo);
|
|
383
426
|
|
|
384
427
|
const darkLogoPath =
|
|
385
428
|
args.darkLogo != null
|
|
@@ -498,12 +541,12 @@ export const generate: CommandFunction<{
|
|
|
498
541
|
log.title("🤖", "Android");
|
|
499
542
|
|
|
500
543
|
const valuesPath = path.resolve(androidResPath, "values");
|
|
501
|
-
|
|
544
|
+
hfs.ensureDir(valuesPath);
|
|
502
545
|
|
|
503
546
|
const colorsXmlPath = path.resolve(valuesPath, "colors.xml");
|
|
504
547
|
const colorsXmlEntry = `<color name="bootsplash_background">${background.hex}</color>`;
|
|
505
548
|
|
|
506
|
-
if (
|
|
549
|
+
if (hfs.exists(colorsXmlPath)) {
|
|
507
550
|
const { root, formatOptions } = readXml(colorsXmlPath);
|
|
508
551
|
const nextColor = parseHtml(colorsXmlEntry);
|
|
509
552
|
const prevColor = root.querySelector(
|
|
@@ -534,7 +577,7 @@ export const generate: CommandFunction<{
|
|
|
534
577
|
`drawable-${suffix}`,
|
|
535
578
|
);
|
|
536
579
|
|
|
537
|
-
|
|
580
|
+
hfs.ensureDir(drawableDirPath);
|
|
538
581
|
|
|
539
582
|
// https://developer.android.com/develop/ui/views/launch/splash-screen#dimensions
|
|
540
583
|
const canvasSize = 288 * ratio;
|
|
@@ -594,13 +637,39 @@ export const generate: CommandFunction<{
|
|
|
594
637
|
{ whiteSpaceAtEndOfSelfclosingTag: false },
|
|
595
638
|
);
|
|
596
639
|
|
|
640
|
+
addFileToXcodeProject(
|
|
641
|
+
path.join(path.basename(iosProjectPath), "BootSplash.storyboard"),
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
const infoPlistPath = path.join(iosProjectPath, "Info.plist");
|
|
645
|
+
|
|
646
|
+
const infoPlist = plist.parse(hfs.text(infoPlistPath)) as Record<
|
|
647
|
+
string,
|
|
648
|
+
unknown
|
|
649
|
+
>;
|
|
650
|
+
|
|
651
|
+
infoPlist["UILaunchStoryboardName"] = "BootSplash.storyboard";
|
|
652
|
+
|
|
653
|
+
const formatted = formatXml(plist.build(infoPlist), {
|
|
654
|
+
collapseContent: true,
|
|
655
|
+
forceSelfClosingEmptyTag: false,
|
|
656
|
+
indentation: "\t",
|
|
657
|
+
lineSeparator: "\n",
|
|
658
|
+
whiteSpaceAtEndOfSelfclosingTag: false,
|
|
659
|
+
})
|
|
660
|
+
.replace(/<string\/>/gm, "<string></string>")
|
|
661
|
+
.replace(/^\t/gm, "");
|
|
662
|
+
|
|
663
|
+
hfs.write(infoPlistPath, formatted);
|
|
664
|
+
logWrite(infoPlistPath);
|
|
665
|
+
|
|
597
666
|
const imageSetPath = path.resolve(
|
|
598
667
|
iosProjectPath,
|
|
599
668
|
"Images.xcassets",
|
|
600
669
|
"BootSplashLogo.imageset",
|
|
601
670
|
);
|
|
602
671
|
|
|
603
|
-
|
|
672
|
+
hfs.ensureDir(imageSetPath);
|
|
604
673
|
cleanIOSAssets(imageSetPath, "bootsplash_logo");
|
|
605
674
|
|
|
606
675
|
const logoFileName = await getIOSAssetFileName({
|
|
@@ -665,7 +734,7 @@ export const generate: CommandFunction<{
|
|
|
665
734
|
|
|
666
735
|
const base64 = (
|
|
667
736
|
format === "svg"
|
|
668
|
-
?
|
|
737
|
+
? hfs.buffer(logoPath)
|
|
669
738
|
: await logo
|
|
670
739
|
.clone()
|
|
671
740
|
.resize(Math.round(logoWidth * 2))
|
|
@@ -723,7 +792,7 @@ export const generate: CommandFunction<{
|
|
|
723
792
|
if (assetsOutputPath != null) {
|
|
724
793
|
log.title("📄", "Assets");
|
|
725
794
|
|
|
726
|
-
|
|
795
|
+
hfs.ensureDir(assetsOutputPath);
|
|
727
796
|
|
|
728
797
|
writeJson(path.resolve(assetsOutputPath, "bootsplash_manifest.json"), {
|
|
729
798
|
background: background.hex,
|