react-native-custom-splash 3.0.2 ā 3.0.3
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/package.json +1 -1
- package/plugin/src/withCustomSplash.js +135 -88
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-custom-splash",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "A custom splash screen module for React Native with native iOS and Android support, fully compatible with Expo",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -2,12 +2,14 @@ const { withDangerousMod } = require('@expo/config-plugins');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* BULLET-PROOF iOS Splash Screen
|
|
7
|
+
* This completely replaces Expo's splash with user's custom splash
|
|
8
|
+
*/
|
|
5
9
|
function withForcediOSSplash(config, pluginConfig) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ios: { ...config.ios, splash: undefined }
|
|
10
|
-
};
|
|
10
|
+
// COMPLETELY DISABLE Expo's splash
|
|
11
|
+
if (config.splash) delete config.splash;
|
|
12
|
+
if (config.ios && config.ios.splash) delete config.ios.splash;
|
|
11
13
|
|
|
12
14
|
return withDangerousMod(config, [
|
|
13
15
|
'ios',
|
|
@@ -15,111 +17,122 @@ function withForcediOSSplash(config, pluginConfig) {
|
|
|
15
17
|
const projectRoot = config.modRequest.projectRoot;
|
|
16
18
|
const iosPath = config.modRequest.platformProjectRoot;
|
|
17
19
|
const projectName = config.modRequest.projectName;
|
|
20
|
+
const projectDir = path.join(iosPath, projectName);
|
|
21
|
+
const assetsPath = path.join(projectDir, 'Images.xcassets');
|
|
18
22
|
|
|
19
|
-
console.log('\nš„
|
|
23
|
+
console.log('\nš„ CUSTOM SPLASH SCREEN SETUP...\n');
|
|
20
24
|
|
|
21
|
-
//
|
|
22
|
-
const
|
|
25
|
+
// STEP 1: DELETE ALL EXPO SPLASH FILES
|
|
26
|
+
const filesToDelete = [
|
|
23
27
|
'SplashScreen.storyboard',
|
|
24
28
|
'LaunchScreen.storyboard',
|
|
25
|
-
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const foldersToDelete = [
|
|
26
32
|
'Images.xcassets/SplashScreen.imageset',
|
|
27
33
|
'Images.xcassets/SplashScreenBackground.imageset',
|
|
34
|
+
'Images.xcassets/SplashScreenLegacy.imageset',
|
|
28
35
|
];
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
const fullPath = path.join(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} else {
|
|
37
|
-
fs.unlinkSync(fullPath);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
} catch (e) { }
|
|
37
|
+
filesToDelete.forEach(file => {
|
|
38
|
+
const fullPath = path.join(projectDir, file);
|
|
39
|
+
if (fs.existsSync(fullPath)) {
|
|
40
|
+
fs.unlinkSync(fullPath);
|
|
41
|
+
console.log('šļø Deleted:', file);
|
|
42
|
+
}
|
|
41
43
|
});
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
foldersToDelete.forEach(folder => {
|
|
46
|
+
const fullPath = path.join(projectDir, folder);
|
|
47
|
+
if (fs.existsSync(fullPath)) {
|
|
48
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
49
|
+
console.log('šļø Deleted:', folder);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// STEP 2: UPDATE INFO.PLIST
|
|
54
|
+
const plistPath = path.join(projectDir, 'Info.plist');
|
|
45
55
|
if (fs.existsSync(plistPath)) {
|
|
46
56
|
let plist = fs.readFileSync(plistPath, 'utf8');
|
|
47
|
-
|
|
57
|
+
|
|
58
|
+
// Remove old references
|
|
59
|
+
plist = plist.replace(/<key>UILaunchStoryboardName<\/key>\s*<string>.*?<\/string>/gs, '');
|
|
48
60
|
plist = plist.replace(/<key>UILaunchScreen<\/key>[\s\S]*?<\/dict>/g, '');
|
|
49
61
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
// Add LaunchScreen reference
|
|
63
|
+
plist = plist.replace(
|
|
64
|
+
'</dict>\n</plist>',
|
|
65
|
+
'\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n</dict>\n</plist>'
|
|
66
|
+
);
|
|
53
67
|
|
|
54
68
|
fs.writeFileSync(plistPath, plist);
|
|
69
|
+
console.log('ā
Info.plist updated');
|
|
55
70
|
}
|
|
56
71
|
|
|
57
|
-
|
|
58
|
-
let
|
|
72
|
+
// STEP 3: COPY USER IMAGES
|
|
73
|
+
let hasBackground = false;
|
|
59
74
|
let hasLogo = false;
|
|
60
75
|
|
|
61
|
-
// Copy background image
|
|
62
76
|
if (pluginConfig.image) {
|
|
63
77
|
const srcPath = path.join(projectRoot, pluginConfig.image);
|
|
64
78
|
if (fs.existsSync(srcPath)) {
|
|
65
|
-
const imagesetDir = path.join(assetsPath, '
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
const imagesetDir = path.join(assetsPath, 'SplashBackground.imageset');
|
|
80
|
+
if (fs.existsSync(imagesetDir)) {
|
|
81
|
+
fs.rmSync(imagesetDir, { recursive: true, force: true });
|
|
82
|
+
}
|
|
68
83
|
fs.mkdirSync(imagesetDir, { recursive: true });
|
|
69
84
|
|
|
70
|
-
fs.copyFileSync(srcPath, path.join(imagesetDir, '
|
|
71
|
-
|
|
85
|
+
fs.copyFileSync(srcPath, path.join(imagesetDir, 'background.png'));
|
|
72
86
|
fs.writeFileSync(path.join(imagesetDir, 'Contents.json'), JSON.stringify({
|
|
73
87
|
images: [
|
|
74
|
-
{
|
|
75
|
-
{
|
|
76
|
-
{
|
|
88
|
+
{ idiom: 'universal', filename: 'background.png', scale: '1x' },
|
|
89
|
+
{ idiom: 'universal', filename: 'background.png', scale: '2x' },
|
|
90
|
+
{ idiom: 'universal', filename: 'background.png', scale: '3x' }
|
|
77
91
|
],
|
|
78
92
|
info: { author: 'xcode', version: 1 }
|
|
79
93
|
}, null, 2));
|
|
80
94
|
|
|
81
|
-
|
|
82
|
-
console.log('ā
Background
|
|
95
|
+
hasBackground = true;
|
|
96
|
+
console.log('ā
Background image: SplashBackground');
|
|
83
97
|
}
|
|
84
98
|
}
|
|
85
99
|
|
|
86
|
-
// Copy logo
|
|
87
100
|
if (pluginConfig.logo) {
|
|
88
101
|
const srcPath = path.join(projectRoot, pluginConfig.logo);
|
|
89
102
|
if (fs.existsSync(srcPath)) {
|
|
90
|
-
const imagesetDir = path.join(assetsPath, '
|
|
91
|
-
|
|
92
|
-
|
|
103
|
+
const imagesetDir = path.join(assetsPath, 'SplashLogo.imageset');
|
|
104
|
+
if (fs.existsSync(imagesetDir)) {
|
|
105
|
+
fs.rmSync(imagesetDir, { recursive: true, force: true });
|
|
106
|
+
}
|
|
93
107
|
fs.mkdirSync(imagesetDir, { recursive: true });
|
|
94
108
|
|
|
95
|
-
fs.copyFileSync(srcPath, path.join(imagesetDir, '
|
|
96
|
-
|
|
109
|
+
fs.copyFileSync(srcPath, path.join(imagesetDir, 'logo.png'));
|
|
97
110
|
fs.writeFileSync(path.join(imagesetDir, 'Contents.json'), JSON.stringify({
|
|
98
111
|
images: [
|
|
99
|
-
{
|
|
100
|
-
{
|
|
101
|
-
{
|
|
112
|
+
{ idiom: 'universal', filename: 'logo.png', scale: '1x' },
|
|
113
|
+
{ idiom: 'universal', filename: 'logo.png', scale: '2x' },
|
|
114
|
+
{ idiom: 'universal', filename: 'logo.png', scale: '3x' }
|
|
102
115
|
],
|
|
103
116
|
info: { author: 'xcode', version: 1 }
|
|
104
117
|
}, null, 2));
|
|
105
118
|
|
|
106
119
|
hasLogo = true;
|
|
107
|
-
console.log('ā
Logo
|
|
120
|
+
console.log('ā
Logo image: SplashLogo');
|
|
108
121
|
}
|
|
109
122
|
}
|
|
110
123
|
|
|
111
|
-
//
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
const
|
|
124
|
+
// STEP 4: CREATE CLEAN LAUNCHSCREEN.STORYBOARD
|
|
125
|
+
const bgColor = pluginConfig.backgroundColor || '#FFFFFF';
|
|
126
|
+
const color = bgColor.replace('#', '');
|
|
127
|
+
const r = (parseInt(color.substr(0, 2), 16) / 255).toFixed(6);
|
|
128
|
+
const g = (parseInt(color.substr(2, 2), 16) / 255).toFixed(6);
|
|
129
|
+
const b = (parseInt(color.substr(4, 2), 16) / 255).toFixed(6);
|
|
116
130
|
|
|
117
|
-
|
|
118
|
-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="
|
|
119
|
-
<device id="
|
|
131
|
+
let storyboard = `<?xml version="1.0" encoding="UTF-8"?>
|
|
132
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
|
133
|
+
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
|
120
134
|
<dependencies>
|
|
121
|
-
<
|
|
122
|
-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
|
|
135
|
+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
|
|
123
136
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
124
137
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
125
138
|
</dependencies>
|
|
@@ -127,51 +140,85 @@ function withForcediOSSplash(config, pluginConfig) {
|
|
|
127
140
|
<scene sceneID="EHf-IW-A2E">
|
|
128
141
|
<objects>
|
|
129
142
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
|
130
|
-
<view key="view" contentMode="scaleToFill" id="
|
|
131
|
-
<rect key="frame" x="0.0" y="0.0" width="
|
|
143
|
+
<view key="view" contentMode="scaleToFill" id="mainView">
|
|
144
|
+
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
|
132
145
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
133
|
-
<subviews
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
<subviews>`;
|
|
147
|
+
|
|
148
|
+
// Add background image if exists
|
|
149
|
+
if (hasBackground) {
|
|
150
|
+
storyboard += `
|
|
151
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SplashBackground" translatesAutoresizingMaskIntoConstraints="NO" id="backgroundImageView">
|
|
152
|
+
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
|
153
|
+
</imageView>`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Add logo if exists
|
|
157
|
+
if (hasLogo) {
|
|
158
|
+
storyboard += `
|
|
159
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SplashLogo" translatesAutoresizingMaskIntoConstraints="NO" id="logoImageView">
|
|
160
|
+
<rect key="frame" x="121.5" y="376" width="150" height="100"/>
|
|
139
161
|
<constraints>
|
|
140
|
-
<constraint firstAttribute="width" constant="150" id="
|
|
141
|
-
<constraint firstAttribute="height" constant="
|
|
162
|
+
<constraint firstAttribute="width" constant="150" id="logoWidth"/>
|
|
163
|
+
<constraint firstAttribute="height" constant="100" id="logoHeight"/>
|
|
142
164
|
</constraints>
|
|
143
|
-
</imageView
|
|
165
|
+
</imageView>`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
storyboard += `
|
|
144
169
|
</subviews>
|
|
145
|
-
<viewLayoutGuide key="safeArea" id="
|
|
170
|
+
<viewLayoutGuide key="safeArea" id="safeAreaGuide"/>
|
|
146
171
|
<color key="backgroundColor" red="${r}" green="${g}" blue="${b}" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
147
|
-
<constraints
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
<constraint firstItem="
|
|
153
|
-
<constraint firstItem="
|
|
172
|
+
<constraints>`;
|
|
173
|
+
|
|
174
|
+
// Add background constraints
|
|
175
|
+
if (hasBackground) {
|
|
176
|
+
storyboard += `
|
|
177
|
+
<constraint firstItem="backgroundImageView" firstAttribute="top" secondItem="mainView" secondAttribute="top" id="bgTop"/>
|
|
178
|
+
<constraint firstItem="backgroundImageView" firstAttribute="leading" secondItem="mainView" secondAttribute="leading" id="bgLeading"/>
|
|
179
|
+
<constraint firstItem="backgroundImageView" firstAttribute="trailing" secondItem="mainView" secondAttribute="trailing" id="bgTrailing"/>
|
|
180
|
+
<constraint firstItem="backgroundImageView" firstAttribute="bottom" secondItem="mainView" secondAttribute="bottom" id="bgBottom"/>`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Add logo constraints
|
|
184
|
+
if (hasLogo) {
|
|
185
|
+
storyboard += `
|
|
186
|
+
<constraint firstItem="logoImageView" firstAttribute="centerX" secondItem="mainView" secondAttribute="centerX" id="logoCenterX"/>
|
|
187
|
+
<constraint firstItem="logoImageView" firstAttribute="centerY" secondItem="mainView" secondAttribute="centerY" id="logoCenterY"/>`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
storyboard += `
|
|
154
191
|
</constraints>
|
|
155
192
|
</view>
|
|
156
193
|
</viewController>
|
|
157
|
-
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
194
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
|
158
195
|
</objects>
|
|
159
|
-
<point key="canvasLocation" x="
|
|
196
|
+
<point key="canvasLocation" x="0" y="0"/>
|
|
160
197
|
</scene>
|
|
161
198
|
</scenes>
|
|
162
|
-
<resources
|
|
163
|
-
|
|
164
|
-
|
|
199
|
+
<resources>`;
|
|
200
|
+
|
|
201
|
+
if (hasBackground) {
|
|
202
|
+
storyboard += `
|
|
203
|
+
<image name="SplashBackground" width="1242" height="2688"/>`;
|
|
204
|
+
}
|
|
205
|
+
if (hasLogo) {
|
|
206
|
+
storyboard += `
|
|
207
|
+
<image name="SplashLogo" width="512" height="512"/>`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
storyboard += `
|
|
165
211
|
</resources>
|
|
166
212
|
</document>`;
|
|
167
213
|
|
|
168
|
-
|
|
169
|
-
|
|
214
|
+
// Write storyboard
|
|
215
|
+
const storyboardPath = path.join(projectDir, 'LaunchScreen.storyboard');
|
|
170
216
|
fs.writeFileSync(storyboardPath, storyboard);
|
|
171
217
|
|
|
172
|
-
console.log('ā
LaunchScreen.storyboard created
|
|
173
|
-
console.log(` Background: ${
|
|
174
|
-
console.log(` Logo: ${hasLogo ? 'YES' : 'NO'}
|
|
218
|
+
console.log('ā
LaunchScreen.storyboard created');
|
|
219
|
+
console.log(` šø Background: ${hasBackground ? 'YES' : 'NO'}`);
|
|
220
|
+
console.log(` šØ Logo: ${hasLogo ? 'YES' : 'NO'}`);
|
|
221
|
+
console.log(` š Color: ${bgColor}\n`);
|
|
175
222
|
|
|
176
223
|
return config;
|
|
177
224
|
},
|