react-native-bootsplash 6.0.0-beta.0 → 6.0.0-beta.10

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.
Files changed (37) hide show
  1. package/README.md +33 -88
  2. package/android/src/main/res/values/public.xml +1 -0
  3. package/android/src/main/res/values/styles.xml +9 -6
  4. package/android/src/main/res/values-night/styles.xml +1 -1
  5. package/android/src/main/res/values-v23/styles.xml +6 -1
  6. package/android/src/main/res/values-v27/styles.xml +1 -1
  7. package/android/src/main/res/values-v29/styles.xml +1 -1
  8. package/android/src/main/res/values-v30/styles.xml +1 -1
  9. package/app.plugin.js +2 -2
  10. package/dist/commonjs/addon/index.js +43 -38
  11. package/dist/commonjs/addon/index.js.map +1 -1
  12. package/dist/commonjs/expo.js +283 -0
  13. package/dist/commonjs/expo.js.map +1 -0
  14. package/dist/commonjs/generate.js +165 -323
  15. package/dist/commonjs/generate.js.map +1 -1
  16. package/dist/commonjs/index.js +3 -3
  17. package/dist/commonjs/index.js.map +1 -1
  18. package/dist/module/addon/index.js +43 -38
  19. package/dist/module/addon/index.js.map +1 -1
  20. package/dist/module/expo.js +273 -0
  21. package/dist/module/expo.js.map +1 -0
  22. package/dist/module/generate.js +162 -317
  23. package/dist/module/generate.js.map +1 -1
  24. package/dist/module/index.js +2 -2
  25. package/dist/module/index.js.map +1 -1
  26. package/dist/typescript/addon/index.d.ts.map +1 -1
  27. package/dist/typescript/expo.d.ts +11 -0
  28. package/dist/typescript/expo.d.ts.map +1 -0
  29. package/dist/typescript/generate.d.ts +27 -21
  30. package/dist/typescript/generate.d.ts.map +1 -1
  31. package/dist/typescript/index.d.ts +22 -4
  32. package/dist/typescript/index.d.ts.map +1 -1
  33. package/ios/RNBootSplash.mm +33 -37
  34. package/package.json +8 -8
  35. package/src/expo.ts +368 -0
  36. package/src/generate.ts +235 -403
  37. package/src/index.ts +32 -10
@@ -1,24 +1,28 @@
1
- import murmurhash from "@emotion/hash";
2
- import { getConfig as getExpoConfig } from "@expo/config";
3
1
  import * as Expo from "@expo/config-plugins";
4
- import { assignColorValue } from "@expo/config-plugins/build/android/Colors";
5
- import { addImports } from "@expo/config-plugins/build/android/codeMod";
6
- import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";
7
2
  import plist from "@expo/plist";
8
3
  import { findProjectRoot } from "@react-native-community/cli-tools";
4
+ import childProcess from "child_process";
5
+ import crypto from "crypto";
9
6
  import detectIndent from "detect-indent";
10
7
  import fs from "fs-extra";
11
- import { parse as parseHtml } from "node-html-parser";
8
+ import { HTMLElement, parse as parseHtml } from "node-html-parser";
12
9
  import path from "path";
13
10
  import pc from "picocolors";
14
11
  import * as htmlPlugin from "prettier/plugins/html";
15
12
  import * as cssPlugin from "prettier/plugins/postcss";
16
13
  import * as prettier from "prettier/standalone";
14
+ import semver from "semver";
17
15
  import sharp from "sharp";
18
16
  import { dedent } from "ts-dedent";
17
+ import util from "util";
19
18
  import formatXml from "xml-formatter";
20
19
  const workingPath = process.env.INIT_CWD ?? process.env.PWD ?? process.cwd();
21
20
  const projectRoot = findProjectRoot(workingPath);
21
+ const promisifiedExec = util.promisify(childProcess.exec);
22
+ const exec = cmd => promisifiedExec(cmd).then(({
23
+ stdout,
24
+ stderr
25
+ }) => stdout || stderr);
22
26
  export const log = {
23
27
  error: text => {
24
28
  console.log(pc.red(`❌ ${text}`));
@@ -33,7 +37,7 @@ export const log = {
33
37
  console.log(` ${path.relative(workingPath, filePath)}` + (dimensions != null ? ` (${dimensions.width}x${dimensions.height})` : ""));
34
38
  }
35
39
  };
36
- export const parseColor = value => {
40
+ const parseColor = value => {
37
41
  const up = value.toUpperCase().replace(/[^0-9A-F]/g, "");
38
42
  if (up.length !== 3 && up.length !== 6) {
39
43
  log.error(`"${value}" value is not a valid hexadecimal color.`);
@@ -151,62 +155,76 @@ export const hfs = {
151
155
  fs.writeFileSync(path, trimmed === "" ? trimmed : trimmed + "\n", "utf-8");
152
156
  }
153
157
  };
158
+ export const getExpoConfig = projectRoot => {
159
+ try {
160
+ const pkg = hfs.json(path.resolve(projectRoot, "node_modules", "expo", "package.json"));
161
+ const version = pkg.version;
162
+ if (version == null || semver.lt(version, "51.0.20")) {
163
+ log.error("Requires Expo 51.0.20 (or higher)");
164
+ process.exit(1);
165
+ }
166
+ return {
167
+ isExpo: true
168
+ };
169
+ } catch {
170
+ return {
171
+ isExpo: false
172
+ };
173
+ }
174
+ };
154
175
  export const writeJson = (filePath, content) => {
155
176
  hfs.write(filePath, JSON.stringify(content, null, 2));
156
177
  log.write(filePath);
157
178
  };
158
- export const readXml = filePath => {
159
- const xml = hfs.text(filePath);
160
- const {
161
- indent
162
- } = detectIndent(xml);
163
- const formatOptions = {
164
- indentation: indent || " "
165
- };
166
- return {
167
- root: parseHtml(xml),
168
- formatOptions
169
- };
170
- };
171
- export const writeXml = (filePath, content, options) => {
172
- const formatted = formatXml(content, {
173
- collapseContent: true,
174
- forceSelfClosingEmptyTag: true,
175
- indentation: " ",
176
- lineSeparator: "\n",
177
- whiteSpaceAtEndOfSelfclosingTag: true,
178
- ...options
179
- });
180
- hfs.write(filePath, formatted);
181
- log.write(filePath);
182
- };
183
- export const readHtml = filePath => {
184
- const html = hfs.text(filePath);
185
- const {
186
- type,
187
- amount
188
- } = detectIndent(html);
189
- const formatOptions = {
190
- useTabs: type === "tab",
191
- tabWidth: amount || 2
192
- };
179
+ export const readXmlLike = filePath => {
180
+ const content = hfs.text(filePath);
193
181
  return {
194
- root: parseHtml(html),
195
- formatOptions
182
+ root: parseHtml(content),
183
+ formatOptions: {
184
+ indent: detectIndent(content)
185
+ }
196
186
  };
197
187
  };
198
- export const writeHtml = async (filePath, content, options) => {
199
- const formatted = await prettier.format(content, {
200
- parser: "html",
201
- plugins: [htmlPlugin, cssPlugin],
202
- tabWidth: 2,
203
- useTabs: false,
204
- ...options
205
- });
206
- hfs.write(filePath, formatted);
207
- log.write(filePath);
188
+ export const writeXmlLike = async (filePath, content, {
189
+ indent,
190
+ ...formatOptions
191
+ }) => {
192
+ if (formatOptions.formatter === "prettier") {
193
+ const {
194
+ formatter,
195
+ useCssPlugin = false,
196
+ selfClosingTags = false,
197
+ ...options
198
+ } = formatOptions;
199
+ const formatted = await prettier.format(content, {
200
+ parser: "html",
201
+ bracketSameLine: true,
202
+ printWidth: 10000,
203
+ plugins: [htmlPlugin, ...(useCssPlugin ? [cssPlugin] : [])],
204
+ useTabs: indent?.type === "tab",
205
+ tabWidth: (indent?.amount ?? 0) || 2,
206
+ ...options
207
+ });
208
+ hfs.write(filePath, selfClosingTags ? formatted.replace(/><\/[a-z-0-9]+>/gi, " />") : formatted);
209
+ log.write(filePath);
210
+ } else {
211
+ const {
212
+ formatter,
213
+ ...options
214
+ } = formatOptions;
215
+ const formatted = formatXml(content, {
216
+ collapseContent: true,
217
+ forceSelfClosingEmptyTag: true,
218
+ lineSeparator: "\n",
219
+ whiteSpaceAtEndOfSelfclosingTag: true,
220
+ indentation: (indent?.indent ?? "") || " ",
221
+ ...options
222
+ });
223
+ hfs.write(filePath, formatted);
224
+ log.write(filePath);
225
+ }
208
226
  };
209
- const cleanIOS = dir => {
227
+ export const cleanIOSAssets = dir => {
210
228
  hfs.readDir(dir).filter(file => file === "Colors.xcassets" || file === "Images.xcassets").map(file => path.join(dir, file)).flatMap(dir => hfs.readDir(dir).filter(file => file.startsWith("BootSplash")).map(file => path.join(dir, file))).forEach(file => {
211
229
  hfs.rm(file);
212
230
  });
@@ -240,7 +258,9 @@ const getFileNameSuffix = async ({
240
258
  darkBrand: darkBrandHash
241
259
  };
242
260
  const stableKey = Object.keys(record).sort().map(key => record[key]).join();
243
- return murmurhash(stableKey);
261
+ return crypto.createHash("shake256", {
262
+ outputLength: 3
263
+ }).update(stableKey).digest("hex").toLowerCase();
244
264
  };
245
265
  const ensureSupportedFormat = async (name, image) => {
246
266
  if (image == null) {
@@ -290,8 +310,8 @@ const getAndroidOutputPath = ({
290
310
  return androidOutputPath;
291
311
  };
292
312
  const getIOSOutputPath = ({
293
- assetsOutputPath,
294
313
  ios,
314
+ assetsOutputPath,
295
315
  isExpo,
296
316
  platforms
297
317
  }) => {
@@ -313,20 +333,30 @@ const getIOSOutputPath = ({
313
333
  }
314
334
  return iosOutputPath;
315
335
  };
316
- const getHtmlTemplatePath = ({
336
+ const getHtmlTemplatePath = async ({
337
+ isExpo,
317
338
  html,
318
339
  platforms
319
340
  }) => {
320
341
  if (!platforms.includes("web")) {
321
342
  return;
322
343
  }
344
+ if (isExpo) {
345
+ const htmlTemplatePath = path.resolve(workingPath, html);
346
+ const htmlTemplateRelativePath = path.relative(workingPath, htmlTemplatePath);
347
+ if (htmlTemplateRelativePath === "public/index.html" && !hfs.exists(htmlTemplatePath)) {
348
+ const cmd = `npx expo customize ${htmlTemplateRelativePath}`;
349
+ console.log(pc.dim(`Running ${cmd}`));
350
+ await exec(cmd);
351
+ }
352
+ }
323
353
  const htmlTemplatePath = path.resolve(workingPath, html);
324
354
  if (!hfs.exists(htmlTemplatePath)) {
325
355
  return log.warn(`No ${path.relative(workingPath, htmlTemplatePath)} file found. Skipping HTML + CSS generation…`);
326
356
  }
327
357
  return htmlTemplatePath;
328
358
  };
329
- export const getImageHeight = (image, width) => {
359
+ const getImageHeight = (image, width) => {
330
360
  if (image == null) {
331
361
  return Promise.resolve(0);
332
362
  }
@@ -350,12 +380,10 @@ export const generate = async ({
350
380
  licenseKey,
351
381
  ...args
352
382
  }) => {
353
- const isExpo = getExpoConfig(projectRoot, {
354
- skipSDKVersionRequirement: true
355
- }).exp.sdkVersion != null;
356
- const [nodeStringVersion = ""] = process.versions.node.split(".");
357
- const nodeVersion = Number.parseInt(nodeStringVersion, 10);
358
- if (!Number.isNaN(nodeVersion) && nodeVersion < 18) {
383
+ const {
384
+ isExpo
385
+ } = getExpoConfig(workingPath);
386
+ if (semver.lt(process.versions.node, "18.0.0")) {
359
387
  log.error("Requires Node 18 (or higher)");
360
388
  process.exit(1);
361
389
  }
@@ -424,7 +452,8 @@ export const generate = async ({
424
452
  isExpo,
425
453
  platforms
426
454
  });
427
- const htmlTemplatePath = getHtmlTemplatePath({
455
+ const htmlTemplatePath = await getHtmlTemplatePath({
456
+ isExpo,
428
457
  html,
429
458
  platforms
430
459
  });
@@ -483,43 +512,85 @@ export const generate = async ({
483
512
  });
484
513
  }));
485
514
  if (!isExpo) {
515
+ const manifestXmlPath = path.resolve(androidOutputPath, "..", "AndroidManifest.xml");
516
+ const manifestXml = readXmlLike(manifestXmlPath);
517
+ const activities = manifestXml.root.querySelectorAll("activity");
518
+ for (const activity of activities) {
519
+ if (activity.getAttribute("android:name") === ".MainActivity") {
520
+ activity.setAttribute("android:theme", "@style/BootTheme");
521
+ }
522
+ }
523
+ await writeXmlLike(manifestXmlPath, manifestXml.root.toString(), {
524
+ ...manifestXml.formatOptions,
525
+ formatter: "prettier",
526
+ htmlWhitespaceSensitivity: "ignore",
527
+ selfClosingTags: true,
528
+ singleAttributePerLine: true
529
+ });
486
530
  const valuesPath = path.resolve(androidOutputPath, "values");
487
531
  hfs.ensureDir(valuesPath);
488
532
  const colorsXmlPath = path.resolve(valuesPath, "colors.xml");
489
533
  const colorsXmlEntry = `<color name="bootsplash_background">${background.hex}</color>`;
490
534
  if (hfs.exists(colorsXmlPath)) {
491
- const {
492
- root,
493
- formatOptions
494
- } = readXml(colorsXmlPath);
535
+ const colorsXml = readXmlLike(colorsXmlPath);
495
536
  const nextColor = parseHtml(colorsXmlEntry);
496
- const prevColor = root.querySelector('color[name="bootsplash_background"]');
537
+ const prevColor = colorsXml.root.querySelector('color[name="bootsplash_background"]');
497
538
  if (prevColor != null) {
498
539
  prevColor.replaceWith(nextColor);
499
540
  } else {
500
- root.querySelector("resources")?.appendChild(nextColor);
541
+ colorsXml.root.querySelector("resources")?.appendChild(nextColor);
501
542
  }
502
- writeXml(colorsXmlPath, root.toString(), formatOptions);
543
+ await writeXmlLike(colorsXmlPath, colorsXml.root.toString(), {
544
+ ...colorsXml.formatOptions,
545
+ formatter: "xmlFormatter"
546
+ });
503
547
  } else {
504
- writeXml(colorsXmlPath, `<resources>${colorsXmlEntry}</resources>`);
548
+ await writeXmlLike(colorsXmlPath, `<resources>${colorsXmlEntry}</resources>`, {
549
+ formatter: "xmlFormatter"
550
+ });
505
551
  }
552
+ const stylesXmlPath = path.resolve(valuesPath, "styles.xml");
553
+ const stylesXml = readXmlLike(stylesXmlPath);
554
+ const prevStyle = stylesXml.root.querySelector('style[name="BootTheme"]');
555
+ const parent = prevStyle?.getAttribute("parent") ?? "Theme.BootSplash";
556
+ const extraItems = parseHtml(prevStyle?.text.split("\n").map(line => line.trim()).join("") ?? "").childNodes.filter(node => {
557
+ if (!(node instanceof HTMLElement)) {
558
+ return true;
559
+ }
560
+ const name = node.getAttribute("name");
561
+ return name !== "bootSplashBackground" && name !== "bootSplashLogo" && name !== "bootSplashBrand" && name !== "postBootSplashTheme";
562
+ }).map(node => node.toString());
563
+ const styleItems = [...(extraItems.length > 0 ? [...extraItems, ""] : []), '<item name="bootSplashBackground">@color/bootsplash_background</item>', '<item name="bootSplashLogo">@drawable/bootsplash_logo</item>', ...(brand != null && brandPath != null ? ['<item name="bootSplashBrand">@drawable/bootsplash_brand</item>'] : []), '<item name="postBootSplashTheme">@style/AppTheme</item>'];
564
+ const nextStyle = parseHtml(dedent`
565
+ <style name="BootTheme" parent="${parent}">
566
+ ${styleItems.join("\n")}
567
+ </style>
568
+ `);
569
+ prevStyle?.remove(); // remove the existing style
570
+ stylesXml.root.querySelector("resources")?.appendChild(nextStyle);
571
+ await writeXmlLike(stylesXmlPath, stylesXml.root.toString(), {
572
+ ...stylesXml.formatOptions,
573
+ formatter: "prettier",
574
+ htmlWhitespaceSensitivity: "ignore"
575
+ });
506
576
  }
507
577
  }
508
578
  if (iosOutputPath != null) {
509
579
  log.title("🍏", "iOS");
510
580
  hfs.ensureDir(iosOutputPath);
511
- cleanIOS(iosOutputPath);
581
+ cleanIOSAssets(iosOutputPath);
512
582
  const storyboardPath = path.resolve(iosOutputPath, "BootSplash.storyboard");
513
583
  const colorsSetPath = path.resolve(iosOutputPath, "Colors.xcassets", `BootSplashBackground-${fileNameSuffix}.colorset`);
514
584
  const imageSetPath = path.resolve(iosOutputPath, "Images.xcassets", `BootSplashLogo-${fileNameSuffix}.imageset`);
515
585
  hfs.ensureDir(colorsSetPath);
516
586
  hfs.ensureDir(imageSetPath);
517
- writeXml(storyboardPath, getStoryboard({
587
+ await writeXmlLike(storyboardPath, getStoryboard({
518
588
  logoHeight,
519
589
  logoWidth,
520
590
  background: background.rgb,
521
591
  fileNameSuffix
522
592
  }), {
593
+ formatter: "xmlFormatter",
523
594
  whiteSpaceAtEndOfSelfclosingTag: false
524
595
  });
525
596
  writeJson(path.resolve(colorsSetPath, "Contents.json"), {
@@ -603,16 +674,17 @@ export const generate = async ({
603
674
  const xcodeProjectPath = Expo.IOSConfig.Paths.getXcodeProjectPath(projectRoot);
604
675
  const project = Expo.IOSConfig.XcodeUtils.getPbxproj(projectRoot);
605
676
  const projectName = path.basename(iosOutputPath);
677
+ const groupName = path.parse(xcodeProjectPath).name;
606
678
  Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
607
- filepath: path.join(projectName, "BootSplash.storyboard"),
608
- groupName: path.parse(xcodeProjectPath).name,
609
679
  project,
680
+ filepath: path.join(projectName, "BootSplash.storyboard"),
681
+ groupName,
610
682
  isBuildFile: true
611
683
  });
612
684
  Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
613
- filepath: path.join(projectName, "Colors.xcassets"),
614
- groupName: path.parse(xcodeProjectPath).name,
615
685
  project,
686
+ filepath: path.join(projectName, "Colors.xcassets"),
687
+ groupName,
616
688
  isBuildFile: true
617
689
  });
618
690
  hfs.write(pbxprojectPath, project.writeSync());
@@ -621,14 +693,11 @@ export const generate = async ({
621
693
  }
622
694
  if (htmlTemplatePath != null) {
623
695
  log.title("🌐", "Web");
624
- const {
625
- root,
626
- formatOptions
627
- } = readHtml(htmlTemplatePath);
696
+ const htmlTemplate = readXmlLike(htmlTemplatePath);
628
697
  const {
629
698
  format
630
699
  } = await logo.metadata();
631
- const prevStyle = root.querySelector("#bootsplash-style");
700
+ const prevStyle = htmlTemplate.root.querySelector("#bootsplash-style");
632
701
  const base64 = (format === "svg" ? hfs.buffer(logoPath) : await logo.clone().resize(Math.round(logoWidth * 2)).png({
633
702
  quality: 100
634
703
  }).toBuffer()).toString("base64");
@@ -657,9 +726,9 @@ export const generate = async ({
657
726
  if (prevStyle != null) {
658
727
  prevStyle.replaceWith(nextStyle);
659
728
  } else {
660
- root.querySelector("head")?.appendChild(nextStyle);
729
+ htmlTemplate.root.querySelector("head")?.appendChild(nextStyle);
661
730
  }
662
- const prevDiv = root.querySelector("#bootsplash");
731
+ const prevDiv = htmlTemplate.root.querySelector("#bootsplash");
663
732
  const nextDiv = parseHtml(dedent`
664
733
  <div id="bootsplash">
665
734
  <div id="bootsplash-logo"></div>
@@ -668,9 +737,13 @@ export const generate = async ({
668
737
  if (prevDiv != null) {
669
738
  prevDiv.replaceWith(nextDiv);
670
739
  } else {
671
- root.querySelector("body")?.appendChild(nextDiv);
740
+ htmlTemplate.root.querySelector("body")?.appendChild(nextDiv);
672
741
  }
673
- await writeHtml(htmlTemplatePath, root.toString(), formatOptions);
742
+ await writeXmlLike(htmlTemplatePath, htmlTemplate.root.toString(), {
743
+ ...htmlTemplate.formatOptions,
744
+ formatter: "prettier",
745
+ useCssPlugin: true
746
+ });
674
747
  }
675
748
  log.title("📄", "Assets");
676
749
  hfs.ensureDir(assetsOutputPath);
@@ -747,232 +820,4 @@ ${pc.blue("┗━━━━━━━━━━━━━━━━━━━━━━
747
820
  }
748
821
  console.log(`\n💖 Thanks for using ${pc.underline("react-native-bootsplash")}`);
749
822
  };
750
- const withAndroidAssets = (config, props) => Expo.withDangerousMod(config, ["android", config => {
751
- const {
752
- assetsDir = "assets/bootsplash"
753
- } = props;
754
- const {
755
- platformProjectRoot
756
- } = config.modRequest;
757
- const srcDir = path.resolve(workingPath, assetsDir, "android");
758
- const destDir = path.resolve(platformProjectRoot, "app", "src", "main", "res");
759
- for (const drawableDir of hfs.readDir(srcDir)) {
760
- const srcDrawableDir = path.join(srcDir, drawableDir);
761
- const destDrawableDir = path.join(destDir, drawableDir);
762
- hfs.ensureDir(destDrawableDir);
763
- for (const file of hfs.readDir(srcDrawableDir)) {
764
- hfs.copy(path.join(srcDrawableDir, file), path.join(destDrawableDir, file));
765
- }
766
- }
767
- return config;
768
- }]);
769
- const withAndroidManifest = config => Expo.withAndroidManifest(config, config => {
770
- config.modResults.manifest.application?.forEach(application => {
771
- if (application.$["android:name"] === ".MainApplication") {
772
- const {
773
- activity
774
- } = application;
775
- activity?.forEach(activity => {
776
- if (activity.$["android:name"] === ".MainActivity") {
777
- activity.$["android:theme"] = "@style/BootTheme";
778
- }
779
- });
780
- }
781
- });
782
- return config;
783
- });
784
- const withMainActivity = config => Expo.withMainActivity(config, config => {
785
- const {
786
- modResults
787
- } = config;
788
- const {
789
- language
790
- } = modResults;
791
- const withImports = addImports(modResults.contents.replace(/(\/\/ )?setTheme\(R\.style\.AppTheme\)/, "// setTheme(R.style.AppTheme)"), ["android.os.Bundle", "com.zoontek.rnbootsplash.RNBootSplash"], language === "java");
792
-
793
- // indented with 4 spaces
794
- const withInit = mergeContents({
795
- src: withImports,
796
- comment: " //",
797
- tag: "bootsplash-init",
798
- offset: 0,
799
- anchor: /super\.onCreate\(null\)/,
800
- newSrc: " RNBootSplash.init(this, R.style.BootTheme)" + (language === "java" ? ";" : "")
801
- });
802
- return {
803
- ...config,
804
- modResults: {
805
- ...modResults,
806
- contents: withInit.contents
807
- }
808
- };
809
- });
810
- const withAndroidStyles = (config, props) => Expo.withAndroidStyles(config, async config => {
811
- const {
812
- assetsDir = "assets/bootsplash",
813
- edgeToEdge = false
814
- } = props;
815
- const manifest = await hfs.json(path.resolve(workingPath, assetsDir, "manifest.json"));
816
- const item = [{
817
- $: {
818
- name: "postBootSplashTheme"
819
- },
820
- _: "@style/AppTheme"
821
- }, {
822
- $: {
823
- name: "bootSplashBackground"
824
- },
825
- _: "@color/bootsplash_background"
826
- }, {
827
- $: {
828
- name: "bootSplashLogo"
829
- },
830
- _: "@drawable/bootsplash_logo"
831
- }];
832
- if (manifest.brand != null) {
833
- item.push({
834
- $: {
835
- name: "bootSplashBrand"
836
- },
837
- _: "@drawable/bootsplash_brand"
838
- });
839
- }
840
- config.modResults.resources.style?.filter(({
841
- $
842
- }) => $.name !== "BootTheme").push({
843
- item,
844
- $: {
845
- name: "BootTheme",
846
- parent: edgeToEdge ? "Theme.BootSplash" : "Theme.BootSplash.EdgeToEdge"
847
- }
848
- });
849
- return config;
850
- });
851
- const withAndroidColors = (config, props) => Expo.withAndroidColors(config, async config => {
852
- const {
853
- assetsDir = "assets/bootsplash"
854
- } = props;
855
- const manifest = await hfs.json(path.resolve(workingPath, assetsDir, "manifest.json"));
856
- config.modResults = assignColorValue(config.modResults, {
857
- name: "bootsplash_background",
858
- value: manifest.background
859
- });
860
- return config;
861
- });
862
- const withAndroidColorsNight = (config, props) => Expo.withAndroidColorsNight(config, async config => {
863
- const {
864
- assetsDir = "assets/bootsplash"
865
- } = props;
866
- const manifest = await hfs.json(path.resolve(workingPath, assetsDir, "manifest.json"));
867
- if (manifest.darkBackground != null) {
868
- config.modResults = assignColorValue(config.modResults, {
869
- name: "bootsplash_background",
870
- value: manifest.darkBackground
871
- });
872
- }
873
- return config;
874
- });
875
- const withIOSAssets = (config, props) => Expo.withDangerousMod(config, ["ios", config => {
876
- const {
877
- assetsDir = "assets/bootsplash"
878
- } = props;
879
- const {
880
- platformProjectRoot,
881
- projectName = ""
882
- } = config.modRequest;
883
- const srcDir = path.resolve(workingPath, assetsDir, "ios");
884
- const destDir = path.resolve(platformProjectRoot, projectName);
885
- cleanIOS(destDir);
886
- hfs.copy(path.join(srcDir, "BootSplash.storyboard"), path.join(destDir, "BootSplash.storyboard"));
887
- for (const xcassetsDir of ["Colors.xcassets", "Images.xcassets"]) {
888
- const srcXcassetsDir = path.join(srcDir, xcassetsDir);
889
- const destXcassetsDir = path.join(destDir, xcassetsDir);
890
- hfs.ensureDir(destXcassetsDir);
891
- for (const file of hfs.readDir(srcXcassetsDir)) {
892
- hfs.copy(path.join(srcXcassetsDir, file), path.join(destXcassetsDir, file));
893
- }
894
- }
895
- return config;
896
- }]);
897
- const withAppDelegate = config => Expo.withAppDelegate(config, config => {
898
- const [sdkStringVersion = ""] = config.sdkVersion?.split(".") ?? "";
899
- const isAtLeastExpo51 = Number.parseInt(sdkStringVersion, 10) >= 51;
900
- const {
901
- modResults
902
- } = config;
903
- const {
904
- language
905
- } = modResults;
906
- if (language !== "objc" && language !== "objcpp") {
907
- throw new Error(`Cannot modify the project AppDelegate as it's not in a supported language: ${language}`);
908
- }
909
- const withHeader = mergeContents({
910
- src: modResults.contents,
911
- comment: "//",
912
- tag: "bootsplash-header",
913
- offset: 1,
914
- anchor: /#import "AppDelegate\.h"/,
915
- newSrc: '#import "RNBootSplash.h"'
916
- });
917
- const withRootView = mergeContents({
918
- src: withHeader.contents,
919
- comment: "//",
920
- tag: "bootsplash-init",
921
- offset: 0,
922
- anchor: /@end/,
923
- newSrc: isAtLeastExpo51 ? dedent`
924
- - (void)customizeRootView:(RCTRootView *)rootView {
925
- [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView];
926
- }
927
- ` : dedent`
928
- - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps {
929
- UIView *rootView = [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
930
- [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView];
931
- return rootView;
932
- }
933
- `
934
- });
935
- return {
936
- ...config,
937
- modResults: {
938
- ...modResults,
939
- contents: withRootView.contents
940
- }
941
- };
942
- });
943
- const withInfoPlist = config => Expo.withInfoPlist(config, config => {
944
- config.modResults["UILaunchStoryboardName"] = "BootSplash";
945
- return config;
946
- });
947
- const withXcodeProject = config => Expo.withXcodeProject(config, config => {
948
- const {
949
- projectName = ""
950
- } = config.modRequest;
951
- Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
952
- filepath: path.join(projectName, "BootSplash.storyboard"),
953
- groupName: projectName,
954
- project: config.modResults,
955
- isBuildFile: true
956
- });
957
- Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
958
- filepath: path.join(projectName, "Colors.xcassets"),
959
- groupName: projectName,
960
- project: config.modResults,
961
- isBuildFile: true
962
- });
963
- return config;
964
- });
965
- export const withGenerate = (config, props = {}) => {
966
- const plugins = [];
967
- const {
968
- platforms = []
969
- } = config;
970
- if (platforms.includes("android")) {
971
- plugins.push(withAndroidAssets, withAndroidManifest, withMainActivity, withAndroidStyles, withAndroidColors, withAndroidColorsNight);
972
- }
973
- if (platforms.includes("ios")) {
974
- plugins.push(withIOSAssets, withAppDelegate, withInfoPlist, withXcodeProject);
975
- }
976
- return Expo.withPlugins(config, plugins.map(plugin => [plugin, props]));
977
- };
978
823
  //# sourceMappingURL=generate.js.map