react-native-bootsplash 4.0.0-alpha.1 → 4.0.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.
Files changed (31) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +80 -144
  3. package/RNBootSplash.podspec +1 -1
  4. package/{ReactNativeBootsplash.res → RNBootsplash.res} +4 -8
  5. package/android/build.gradle +13 -11
  6. package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplash.java +2 -11
  7. package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashModule.java +79 -198
  8. package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashPackage.java +6 -2
  9. package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashTask.java +1 -15
  10. package/bsconfig.json +0 -1
  11. package/dist/commonjs/generate.js +128 -110
  12. package/dist/commonjs/generate.js.map +1 -1
  13. package/dist/commonjs/index.js +5 -21
  14. package/dist/commonjs/index.js.map +1 -1
  15. package/dist/module/generate.js +124 -107
  16. package/dist/module/generate.js.map +1 -1
  17. package/dist/module/index.js +3 -15
  18. package/dist/module/index.js.map +1 -1
  19. package/dist/typescript/generate.d.ts +4 -4
  20. package/dist/typescript/index.d.ts +0 -6
  21. package/ios/RNBootSplash.h +3 -13
  22. package/ios/RNBootSplash.m +44 -99
  23. package/ios/RNBootSplash.xcodeproj/project.pbxproj +2 -2
  24. package/package.json +19 -21
  25. package/react-native.config.js +21 -8
  26. package/src/generate.ts +116 -138
  27. package/src/index.ts +0 -14
  28. package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashDialog.java +0 -36
  29. package/android/src/main/res/anim/bootsplash_fade_in.xml +0 -7
  30. package/android/src/main/res/anim/bootsplash_fade_out.xml +0 -7
  31. package/android/src/main/res/values/styles.xml +0 -13
package/src/generate.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import chalk from "chalk";
2
2
  import fs from "fs-extra";
3
- import jimp from "jimp";
3
+ import Jimp from "jimp";
4
4
  import path from "path";
5
5
 
6
6
  const logoFileName = "bootsplash_logo";
7
7
  const xcassetName = "BootSplashLogo";
8
+ // https://github.com/androidx/androidx/blob/androidx-main/core/core-splashscreen/src/main/res/values/dimens.xml#L22
9
+ const splashScreenIconSizeNoBackground = 288;
8
10
  const androidColorName = "bootsplash_background";
9
11
  const androidColorRegex = /<color name="bootsplash_background">#\w+<\/color>/g;
10
12
 
@@ -96,17 +98,6 @@ const getStoryboard = ({
96
98
  `;
97
99
  };
98
100
 
99
- const bootSplashXml = `<?xml version="1.0" encoding="utf-8"?>
100
-
101
- <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
102
- <item android:drawable="@color/${androidColorName}" />
103
-
104
- <item>
105
- <bitmap android:src="@mipmap/${logoFileName}" android:gravity="center" />
106
- </item>
107
- </layer-list>
108
- `;
109
-
110
101
  const log = (text: string, dim = false) => {
111
102
  console.log(dim ? chalk.dim(text) : text);
112
103
  };
@@ -127,7 +118,7 @@ export const generate = async ({
127
118
  android,
128
119
  ios,
129
120
 
130
- workingDirectory,
121
+ workingPath,
131
122
  logoPath,
132
123
  backgroundColor,
133
124
  logoWidth,
@@ -142,12 +133,13 @@ export const generate = async ({
142
133
  projectPath: string;
143
134
  } | null;
144
135
 
145
- workingDirectory: string;
136
+ workingPath: string;
146
137
  logoPath: string;
138
+ assetsPath?: string;
139
+
147
140
  backgroundColor: string;
148
- logoWidth: number;
149
141
  flavor: string;
150
- assetsPath?: string;
142
+ logoWidth: number;
151
143
  }) => {
152
144
  if (!isValidHexadecimal(backgroundColor)) {
153
145
  throw new Error(
@@ -155,80 +147,64 @@ export const generate = async ({
155
147
  );
156
148
  }
157
149
 
158
- const image = await jimp.read(logoPath);
150
+ const image = await Jimp.read(logoPath);
159
151
  const backgroundColorHex = toFullHexadecimal(backgroundColor);
160
152
 
161
- const images: {
162
- filePath: string;
163
- width: number;
164
- height: number;
165
- }[] = [];
166
-
167
153
  const getHeight = (size: number) =>
168
154
  Math.ceil(size * (image.bitmap.height / image.bitmap.width));
169
155
 
170
- const width = {
171
- "@1x": logoWidth,
172
- "@1,5x": logoWidth * 1.5,
173
- "@2x": logoWidth * 2,
174
- "@3x": logoWidth * 3,
175
- "@4x": logoWidth * 4,
176
- };
177
-
178
- const height = {
179
- "@1x": getHeight(width["@1x"]),
180
- "@1,5x": getHeight(width["@1,5x"]),
181
- "@2x": getHeight(width["@2x"]),
182
- "@3x": getHeight(width["@3x"]),
183
- "@4x": getHeight(width["@4x"]),
184
- };
156
+ const logWrite = (
157
+ emoji: string,
158
+ filePath: string,
159
+ dimensions?: { width: number; height: number },
160
+ ) =>
161
+ log(
162
+ `${emoji} ${path.relative(workingPath, filePath)}` +
163
+ (dimensions != null
164
+ ? ` (${dimensions.width}x${dimensions.height})`
165
+ : ""),
166
+ );
185
167
 
186
168
  if (assetsPath && fs.existsSync(assetsPath)) {
187
- images.push(
188
- {
189
- filePath: path.resolve(assetsPath, logoFileName + ".png"),
190
- width: width["@1x"],
191
- height: height["@1x"],
192
- },
193
- {
194
- filePath: path.resolve(assetsPath, logoFileName + "@1,5x.png"),
195
- width: width["@1,5x"],
196
- height: height["@1,5x"],
197
- },
198
- {
199
- filePath: path.resolve(assetsPath, logoFileName + "@2x.png"),
200
- width: width["@2x"],
201
- height: height["@2x"],
202
- },
203
- {
204
- filePath: path.resolve(assetsPath, logoFileName + "@3x.png"),
205
- width: width["@3x"],
206
- height: height["@3x"],
207
- },
208
- {
209
- filePath: path.resolve(assetsPath, logoFileName + "@4x.png"),
210
- width: width["@4x"],
211
- height: height["@4x"],
212
- },
169
+ log(`\n ${chalk.underline("Assets")}`);
170
+
171
+ await Promise.all(
172
+ [
173
+ { ratio: 1, suffix: "" },
174
+ { ratio: 1.5, suffix: "@1,5x" },
175
+ { ratio: 2, suffix: "@2x" },
176
+ { ratio: 3, suffix: "@3x" },
177
+ { ratio: 4, suffix: "@4x" },
178
+ ].map(({ ratio, suffix }) => {
179
+ const fileName = `${logoFileName}${suffix}.png`;
180
+ const filePath = path.resolve(assetsPath, fileName);
181
+ const width = logoWidth * ratio;
182
+ const height = getHeight(width);
183
+
184
+ return image
185
+ .clone()
186
+ .resize(width, height)
187
+ .quality(100)
188
+ .writeAsync(filePath)
189
+ .then(() => {
190
+ logWrite("✨", filePath, { width, height });
191
+ });
192
+ }),
213
193
  );
214
194
  }
215
195
 
216
196
  if (android) {
197
+ log(`\n ${chalk.underline("Android")}`);
198
+
217
199
  const appPath = android.appName
218
200
  ? path.resolve(android.sourceDir, android.appName)
219
201
  : path.resolve(android.sourceDir); // @react-native-community/cli 2.x & 3.x support
220
202
 
221
203
  const resPath = path.resolve(appPath, "src", flavor, "res");
222
- const drawablePath = path.resolve(resPath, "drawable");
223
204
  const valuesPath = path.resolve(resPath, "values");
224
205
 
225
- fs.ensureDirSync(drawablePath);
226
206
  fs.ensureDirSync(valuesPath);
227
207
 
228
- const bootSplashXmlPath = path.resolve(drawablePath, "bootsplash.xml");
229
- fs.writeFileSync(bootSplashXmlPath, bootSplashXml, "utf-8");
230
- log(`✨ ${path.relative(workingDirectory, bootSplashXmlPath)}`, true);
231
-
232
208
  const colorsXmlPath = path.resolve(valuesPath, "colors.xml");
233
209
  const colorsXmlEntry = `<color name="${androidColorName}">${backgroundColorHex}</color>`;
234
210
 
@@ -252,7 +228,7 @@ export const generate = async ({
252
228
  );
253
229
  }
254
230
 
255
- log(`✏️ ${path.relative(workingDirectory, colorsXmlPath)}`, true);
231
+ logWrite("✏️ ", colorsXmlPath);
256
232
  } else {
257
233
  fs.writeFileSync(
258
234
  colorsXmlPath,
@@ -260,43 +236,45 @@ export const generate = async ({
260
236
  "utf-8",
261
237
  );
262
238
 
263
- log(`✨ ${path.relative(workingDirectory, colorsXmlPath)}`, true);
239
+ logWrite("✨", colorsXmlPath);
264
240
  }
265
241
 
266
- images.push(
267
- {
268
- filePath: path.resolve(resPath, "mipmap-mdpi", logoFileName + ".png"),
269
- width: width["@1x"],
270
- height: height["@1x"],
271
- },
272
- {
273
- filePath: path.resolve(resPath, "mipmap-hdpi", logoFileName + ".png"),
274
- width: width["@1,5x"],
275
- height: height["@1,5x"],
276
- },
277
- {
278
- filePath: path.resolve(resPath, "mipmap-xhdpi", logoFileName + ".png"),
279
- width: width["@2x"],
280
- height: height["@2x"],
281
- },
282
- {
283
- filePath: path.resolve(resPath, "mipmap-xxhdpi", logoFileName + ".png"),
284
- width: width["@3x"],
285
- height: height["@3x"],
286
- },
287
- {
288
- filePath: path.resolve(
289
- resPath,
290
- "mipmap-xxxhdpi",
291
- logoFileName + ".png",
292
- ),
293
- width: width["@4x"],
294
- height: height["@4x"],
295
- },
242
+ await Promise.all(
243
+ [
244
+ { ratio: 1, directory: "mipmap-mdpi" },
245
+ { ratio: 1.5, directory: "mipmap-hdpi" },
246
+ { ratio: 2, directory: "mipmap-xhdpi" },
247
+ { ratio: 3, directory: "mipmap-xxhdpi" },
248
+ { ratio: 4, directory: "mipmap-xxxhdpi" },
249
+ ].map(({ ratio, directory }) => {
250
+ const fileName = `${logoFileName}.png`;
251
+ const filePath = path.resolve(resPath, directory, fileName);
252
+ const width = logoWidth * ratio;
253
+ const height = getHeight(width);
254
+
255
+ const canvasSize = splashScreenIconSizeNoBackground * ratio;
256
+
257
+ // https://github.com/oliver-moran/jimp/tree/master/packages/jimp#creating-new-images
258
+ const canvas = new Jimp(canvasSize, canvasSize, 0xffffff00);
259
+ const logo = image.clone().resize(width, height);
260
+
261
+ const x = (canvasSize - width) / 2;
262
+ const y = (canvasSize - height) / 2;
263
+
264
+ return canvas
265
+ .blit(logo, x, y)
266
+ .quality(100)
267
+ .writeAsync(filePath)
268
+ .then(() => {
269
+ logWrite("✨", filePath, { width: canvasSize, height: canvasSize });
270
+ });
271
+ }),
296
272
  );
297
273
  }
298
274
 
299
275
  if (ios) {
276
+ log(`\n ${chalk.underline("iOS")}`);
277
+
300
278
  const projectPath = ios.projectPath.replace(/.xcodeproj$/, "");
301
279
  const imagesPath = path.resolve(projectPath, "Images.xcassets");
302
280
 
@@ -306,14 +284,14 @@ export const generate = async ({
306
284
  fs.writeFileSync(
307
285
  storyboardPath,
308
286
  getStoryboard({
309
- height: height["@1x"],
310
- width: width["@1x"],
287
+ height: getHeight(logoWidth),
288
+ width: logoWidth,
311
289
  backgroundColor: backgroundColorHex,
312
290
  }),
313
291
  "utf-8",
314
292
  );
315
293
 
316
- log(`✨ ${path.relative(workingDirectory, storyboardPath)}`, true);
294
+ logWrite("✨", storyboardPath);
317
295
  } else {
318
296
  log(
319
297
  `No "${projectPath}" directory found. Skipping iOS storyboard generation…`,
@@ -330,22 +308,26 @@ export const generate = async ({
330
308
  "utf-8",
331
309
  );
332
310
 
333
- images.push(
334
- {
335
- filePath: path.resolve(imageSetPath, logoFileName + ".png"),
336
- width: width["@1x"],
337
- height: height["@1x"],
338
- },
339
- {
340
- filePath: path.resolve(imageSetPath, logoFileName + "@2x.png"),
341
- width: width["@2x"],
342
- height: height["@2x"],
343
- },
344
- {
345
- filePath: path.resolve(imageSetPath, logoFileName + "@3x.png"),
346
- width: width["@3x"],
347
- height: height["@3x"],
348
- },
311
+ await Promise.all(
312
+ [
313
+ { ratio: 1, suffix: "" },
314
+ { ratio: 2, suffix: "@2x" },
315
+ { ratio: 3, suffix: "@3x" },
316
+ ].map(({ ratio, suffix }) => {
317
+ const fileName = `${logoFileName}${suffix}.png`;
318
+ const filePath = path.resolve(imageSetPath, fileName);
319
+ const width = logoWidth * ratio;
320
+ const height = getHeight(width);
321
+
322
+ return image
323
+ .clone()
324
+ .resize(width, height)
325
+ .quality(100)
326
+ .writeAsync(filePath)
327
+ .then(() => {
328
+ logWrite("✨", filePath, { width, height });
329
+ });
330
+ }),
349
331
  );
350
332
  } else {
351
333
  log(
@@ -354,23 +336,19 @@ export const generate = async ({
354
336
  }
355
337
  }
356
338
 
357
- await Promise.all(
358
- images.map(({ filePath, width, height }) =>
359
- image
360
- .clone()
361
- .cover(width, height)
362
- .writeAsync(filePath)
363
- .then(() => {
364
- log(
365
- `✨ ${path.relative(
366
- workingDirectory,
367
- filePath,
368
- )} (${width}x${height})`,
369
- true,
370
- );
371
- }),
372
- ),
373
- );
339
+ log(`
340
+ ${chalk.blue("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")}
341
+ ${chalk.blue("┃")} 💖 ${chalk.bold(
342
+ "Love this library? Consider sponsoring!",
343
+ )} ${chalk.blue("┃")}
344
+ ${chalk.blue("┃")} One-time amounts are available. ${chalk.blue(
345
+ "┃",
346
+ )}
347
+ ${chalk.blue("┃")} ${chalk.underline(
348
+ "https://github.com/sponsors/zoontek",
349
+ )} ${chalk.blue("┃")}
350
+ ${chalk.blue("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")}
351
+ `);
374
352
 
375
353
  log(
376
354
  `✅ Done! Thanks for using ${chalk.underline("react-native-bootsplash")}.`,
package/src/index.ts CHANGED
@@ -4,17 +4,10 @@ export type VisibilityStatus = "visible" | "hidden" | "transitioning";
4
4
  export type Config = { fade?: boolean };
5
5
 
6
6
  const NativeModule: {
7
- show: (fade: boolean) => Promise<true>;
8
7
  hide: (fade: boolean) => Promise<true>;
9
8
  getVisibilityStatus: () => Promise<VisibilityStatus>;
10
- statusBarHeight?: number;
11
- navigationBarHeight?: number;
12
9
  } = NativeModules.RNBootSplash;
13
10
 
14
- export function show(config: Config = {}): Promise<void> {
15
- return NativeModule.show({ fade: false, ...config }.fade).then(() => {});
16
- }
17
-
18
11
  export function hide(config: Config = {}): Promise<void> {
19
12
  return NativeModule.hide({ fade: false, ...config }.fade).then(() => {});
20
13
  }
@@ -23,14 +16,7 @@ export function getVisibilityStatus(): Promise<VisibilityStatus> {
23
16
  return NativeModule.getVisibilityStatus();
24
17
  }
25
18
 
26
- export const statusBarHeight: number = NativeModule.statusBarHeight ?? 0;
27
- export const navigationBarHeight: number =
28
- NativeModule.navigationBarHeight ?? 0;
29
-
30
19
  export default {
31
- show,
32
20
  hide,
33
21
  getVisibilityStatus,
34
- statusBarHeight,
35
- navigationBarHeight,
36
22
  };
@@ -1,36 +0,0 @@
1
- package com.zoontek.rnbootsplash;
2
-
3
- import android.app.Activity;
4
- import android.app.Dialog;
5
- import android.os.Bundle;
6
- import android.view.Window;
7
- import android.widget.LinearLayout.LayoutParams;
8
-
9
- import androidx.annotation.NonNull;
10
- import androidx.annotation.StyleRes;
11
-
12
- public class RNBootSplashDialog extends Dialog {
13
-
14
- public RNBootSplashDialog(@NonNull final Activity activity,
15
- @StyleRes final int bootThemeResId) {
16
- super(activity, bootThemeResId);
17
- setCancelable(false);
18
- setCanceledOnTouchOutside(false);
19
- }
20
-
21
- @Override
22
- public void onBackPressed() {
23
- // Prevent default behavior
24
- }
25
-
26
- @Override
27
- protected void onCreate(Bundle savedInstanceState) {
28
- Window window = getWindow();
29
-
30
- if (window != null) {
31
- window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
32
- }
33
-
34
- super.onCreate(savedInstanceState);
35
- }
36
- }
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
-
3
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
4
- android:interpolator="@android:interpolator/decelerate_quad"
5
- android:fromAlpha="0.0"
6
- android:toAlpha="1.0"
7
- android:duration="220" />
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
-
3
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
4
- android:interpolator="@android:interpolator/accelerate_quad"
5
- android:fromAlpha="1.0"
6
- android:toAlpha="0.0"
7
- android:duration="220" />
@@ -1,13 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
-
3
- <resources>
4
- <style name="bootsplash_no_animation">
5
- <item name="android:windowEnterAnimation">@null</item>
6
- <item name="android:windowExitAnimation">@null</item>
7
- </style>
8
-
9
- <style name="bootsplash_fade_animation">
10
- <item name="android:windowEnterAnimation">@anim/bootsplash_fade_in</item>
11
- <item name="android:windowExitAnimation">@anim/bootsplash_fade_out</item>
12
- </style>
13
- </resources>