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.
- package/LICENSE +1 -1
- package/README.md +80 -144
- package/RNBootSplash.podspec +1 -1
- package/{ReactNativeBootsplash.res → RNBootsplash.res} +4 -8
- package/android/build.gradle +13 -11
- package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplash.java +2 -11
- package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashModule.java +79 -198
- package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashPackage.java +6 -2
- package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashTask.java +1 -15
- package/bsconfig.json +0 -1
- package/dist/commonjs/generate.js +128 -110
- package/dist/commonjs/generate.js.map +1 -1
- package/dist/commonjs/index.js +5 -21
- package/dist/commonjs/index.js.map +1 -1
- package/dist/module/generate.js +124 -107
- package/dist/module/generate.js.map +1 -1
- package/dist/module/index.js +3 -15
- package/dist/module/index.js.map +1 -1
- package/dist/typescript/generate.d.ts +4 -4
- package/dist/typescript/index.d.ts +0 -6
- package/ios/RNBootSplash.h +3 -13
- package/ios/RNBootSplash.m +44 -99
- package/ios/RNBootSplash.xcodeproj/project.pbxproj +2 -2
- package/package.json +19 -21
- package/react-native.config.js +21 -8
- package/src/generate.ts +116 -138
- package/src/index.ts +0 -14
- package/android/src/main/java/com/zoontek/rnbootsplash/RNBootSplashDialog.java +0 -36
- package/android/src/main/res/anim/bootsplash_fade_in.xml +0 -7
- package/android/src/main/res/anim/bootsplash_fade_out.xml +0 -7
- 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
|
|
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
|
-
|
|
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
|
-
|
|
136
|
+
workingPath: string;
|
|
146
137
|
logoPath: string;
|
|
138
|
+
assetsPath?: string;
|
|
139
|
+
|
|
147
140
|
backgroundColor: string;
|
|
148
|
-
logoWidth: number;
|
|
149
141
|
flavor: string;
|
|
150
|
-
|
|
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
|
|
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
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
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
|
-
|
|
239
|
+
logWrite("✨", colorsXmlPath);
|
|
264
240
|
}
|
|
265
241
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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:
|
|
310
|
-
width:
|
|
287
|
+
height: getHeight(logoWidth),
|
|
288
|
+
width: logoWidth,
|
|
311
289
|
backgroundColor: backgroundColorHex,
|
|
312
290
|
}),
|
|
313
291
|
"utf-8",
|
|
314
292
|
);
|
|
315
293
|
|
|
316
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
filePath
|
|
341
|
-
width
|
|
342
|
-
height
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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,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>
|