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