react-native-custom-splash 3.0.0 → 3.0.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-custom-splash",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
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",
@@ -1,23 +1,21 @@
1
- const { withDangerousMod, withPlugins } = require('@expo/config-plugins');
1
+ const { withDangerousMod } = require('@expo/config-plugins');
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
4
 
5
5
  /**
6
- * ULTIMATE iOS Splash Fix - Forceful & Complete
7
- * This DISABLES Expo's splash and FORCES user images
6
+ * FINAL WORKING iOS Splash - Xcode Compatible
8
7
  */
9
8
  function withForcediOSSplash(config, pluginConfig) {
10
- // STEP 1: Disable Expo's default splash completely
9
+ // Disable Expo's splash
11
10
  config = {
12
11
  ...config,
13
- splash: undefined, // Remove Expo splash config
12
+ splash: undefined,
14
13
  ios: {
15
14
  ...config.ios,
16
- splash: undefined // Remove iOS splash config
15
+ splash: undefined
17
16
  }
18
17
  };
19
18
 
20
- // STEP 2: Use dangerousMod to forcefully set everything
21
19
  return withDangerousMod(config, [
22
20
  'ios',
23
21
  async (config) => {
@@ -25,12 +23,9 @@ function withForcediOSSplash(config, pluginConfig) {
25
23
  const iosPath = config.modRequest.platformProjectRoot;
26
24
  const projectName = config.modRequest.projectName;
27
25
 
28
- console.log('\nļæ½ FORCING CUSTOM SPLASH SCREEN (FINAL FIX)...\n');
26
+ console.log('\nšŸ”„ SETTING UP CUSTOM SPLASH...\n');
29
27
 
30
- // Wait a bit to ensure Expo is done
31
- await new Promise(resolve => setTimeout(resolve, 100));
32
-
33
- // NUCLEAR OPTION: Delete EVERYTHING splash-related
28
+ // Delete ALL old splash files
34
29
  const filesToDelete = [
35
30
  path.join(iosPath, projectName, 'SplashScreen.storyboard'),
36
31
  path.join(iosPath, projectName, 'LaunchScreen.storyboard'),
@@ -47,23 +42,19 @@ function withForcediOSSplash(config, pluginConfig) {
47
42
  } else {
48
43
  fs.unlinkSync(filePath);
49
44
  }
50
- console.log('šŸ—‘ļø Deleted:', path.basename(filePath));
51
45
  }
52
46
  } catch (e) {
53
- // Ignore errors
47
+ // Ignore
54
48
  }
55
49
  });
56
50
 
57
- // Force update Info.plist
51
+ // Update Info.plist
58
52
  const plistPath = path.join(iosPath, projectName, 'Info.plist');
59
53
  if (fs.existsSync(plistPath)) {
60
54
  let plist = fs.readFileSync(plistPath, 'utf8');
61
-
62
- // Remove ALL launch screen configurations
63
55
  plist = plist.replace(/<key>UILaunchStoryboardName<\/key>\s*<string>.*?<\/string>/g, '');
64
56
  plist = plist.replace(/<key>UILaunchScreen<\/key>[\s\S]*?<\/dict>/g, '');
65
57
 
66
- // Add our LaunchScreen BEFORE closing dict
67
58
  if (!plist.includes('UILaunchStoryboardName')) {
68
59
  plist = plist.replace(
69
60
  '</dict>\n</plist>',
@@ -72,169 +63,207 @@ function withForcediOSSplash(config, pluginConfig) {
72
63
  }
73
64
 
74
65
  fs.writeFileSync(plistPath, plist);
75
- console.log('āœ… Info.plist FORCED');
66
+ console.log('āœ… Info.plist updated');
76
67
  }
77
68
 
78
- // Copy user images with FORCE
79
69
  const assetsPath = path.join(iosPath, projectName, 'Images.xcassets');
80
70
  let hasImage = false;
81
71
  let hasLogo = false;
82
72
 
73
+ // Copy splash_image
83
74
  if (pluginConfig.image) {
84
75
  const srcImage = path.join(projectRoot, pluginConfig.image);
85
76
  if (fs.existsSync(srcImage)) {
86
- const destDir = path.join(assetsPath, 'splash_image.imageset');
77
+ const destDir = path.join(assetsPath, 'SplashImage.imageset');
87
78
 
88
- // Force delete and recreate
89
79
  if (fs.existsSync(destDir)) {
90
80
  fs.rmSync(destDir, { recursive: true, force: true });
91
81
  }
92
82
  fs.mkdirSync(destDir, { recursive: true });
93
83
 
94
- // Copy for all scales
95
- ['', '@2x', '@3x'].forEach(scale => {
96
- fs.copyFileSync(srcImage, path.join(destDir, `splash_image${scale}.png`));
97
- });
84
+ // Copy image
85
+ fs.copyFileSync(srcImage, path.join(destDir, 'splash.png'));
86
+
87
+ // Create Contents.json
88
+ const contents = {
89
+ images: [
90
+ {
91
+ filename: 'splash.png',
92
+ idiom: 'universal',
93
+ scale: '1x'
94
+ },
95
+ {
96
+ filename: 'splash.png',
97
+ idiom: 'universal',
98
+ scale: '2x'
99
+ },
100
+ {
101
+ filename: 'splash.png',
102
+ idiom: 'universal',
103
+ scale: '3x'
104
+ }
105
+ ],
106
+ info: {
107
+ author: 'xcode',
108
+ version: 1
109
+ }
110
+ };
98
111
 
99
- // Force Contents.json
100
112
  fs.writeFileSync(
101
113
  path.join(destDir, 'Contents.json'),
102
- JSON.stringify({
103
- images: [
104
- { idiom: 'universal', filename: 'splash_image.png', scale: '1x' },
105
- { idiom: 'universal', filename: 'splash_image@2x.png', scale: '2x' },
106
- { idiom: 'universal', filename: 'splash_image@3x.png', scale: '3x' }
107
- ],
108
- info: { author: 'xcode', version: 1 }
109
- }, null, 2)
114
+ JSON.stringify(contents, null, 2)
110
115
  );
111
116
 
112
117
  hasImage = true;
113
- console.log('āœ… FORCED: splash_image');
118
+ console.log('āœ… Background image copied: SplashImage');
114
119
  }
115
120
  }
116
121
 
122
+ // Copy splash_logo
117
123
  if (pluginConfig.logo) {
118
124
  const srcLogo = path.join(projectRoot, pluginConfig.logo);
119
125
  if (fs.existsSync(srcLogo)) {
120
- const destDir = path.join(assetsPath, 'splash_logo.imageset');
126
+ const destDir = path.join(assetsPath, 'SplashLogo.imageset');
121
127
 
122
- // Force delete and recreate
123
128
  if (fs.existsSync(destDir)) {
124
129
  fs.rmSync(destDir, { recursive: true, force: true });
125
130
  }
126
131
  fs.mkdirSync(destDir, { recursive: true });
127
132
 
128
- // Copy for all scales
129
- ['', '@2x', '@3x'].forEach(scale => {
130
- fs.copyFileSync(srcLogo, path.join(destDir, `splash_logo${scale}.png`));
131
- });
133
+ // Copy logo
134
+ fs.copyFileSync(srcLogo, path.join(destDir, 'logo.png'));
135
+
136
+ // Create Contents.json
137
+ const contents = {
138
+ images: [
139
+ {
140
+ filename: 'logo.png',
141
+ idiom: 'universal',
142
+ scale: '1x'
143
+ },
144
+ {
145
+ filename: 'logo.png',
146
+ idiom: 'universal',
147
+ scale: '2x'
148
+ },
149
+ {
150
+ filename: 'logo.png',
151
+ idiom: 'universal',
152
+ scale: '3x'
153
+ }
154
+ ],
155
+ info: {
156
+ author: 'xcode',
157
+ version: 1
158
+ }
159
+ };
132
160
 
133
- // Force Contents.json
134
161
  fs.writeFileSync(
135
162
  path.join(destDir, 'Contents.json'),
136
- JSON.stringify({
137
- images: [
138
- { idiom: 'universal', filename: 'splash_logo.png', scale: '1x' },
139
- { idiom: 'universal', filename: 'splash_logo@2x.png', scale: '2x' },
140
- { idiom: 'universal', filename: 'splash_logo@3x.png', scale: '3x' }
141
- ],
142
- info: { author: 'xcode', version: 1 }
143
- }, null, 2)
163
+ JSON.stringify(contents, null, 2)
144
164
  );
145
165
 
146
166
  hasLogo = true;
147
- console.log('āœ… FORCED: splash_logo');
167
+ console.log('āœ… Logo image copied: SplashLogo');
148
168
  }
149
169
  }
150
170
 
151
- // FORCE create LaunchScreen.storyboard
152
- const storyboard = createForcedStoryboard(hasImage, hasLogo, pluginConfig.backgroundColor);
171
+ // Create LaunchScreen.storyboard
172
+ const storyboard = createXcodeStoryboard(hasImage, hasLogo, pluginConfig.backgroundColor);
153
173
  const storyboardPath = path.join(iosPath, projectName, 'LaunchScreen.storyboard');
154
174
 
155
- // Delete if exists
156
175
  if (fs.existsSync(storyboardPath)) {
157
176
  fs.unlinkSync(storyboardPath);
158
177
  }
159
178
 
160
- // Write with force
161
- fs.writeFileSync(storyboardPath, storyboard, { flag: 'w' });
179
+ fs.writeFileSync(storyboardPath, storyboard);
162
180
 
163
- console.log('āœ… FORCED: LaunchScreen.storyboard');
164
- console.log(` šŸ–¼ļø Background: ${hasImage ? 'splash_image' : 'color'}`);
165
- console.log(` šŸŽØ Logo: ${hasLogo ? 'splash_logo' : 'none'}`);
166
- console.log(` 🌈 Color: ${pluginConfig.backgroundColor}`);
167
- console.log('\nāœ… CUSTOM SPLASH FORCED SUCCESSFULLY!\n');
181
+ console.log('āœ… LaunchScreen.storyboard created!');
182
+ console.log(` Background: ${hasImage ? 'SplashImage āœ“' : 'Color only'}`);
183
+ console.log(` Logo: ${hasLogo ? 'SplashLogo āœ“' : 'None'}`);
184
+ console.log(` Color: ${pluginConfig.backgroundColor}\n`);
168
185
 
169
186
  return config;
170
187
  },
171
188
  ]);
172
189
  }
173
190
 
174
- function createForcedStoryboard(hasImage, hasLogo, bgColor) {
191
+ function createXcodeStoryboard(hasImage, hasLogo, bgColor) {
175
192
  const color = bgColor.replace('#', '');
176
193
  const r = parseInt(color.substr(0, 2), 16) / 255;
177
194
  const g = parseInt(color.substr(2, 2), 16) / 255;
178
195
  const b = parseInt(color.substr(4, 2), 16) / 255;
179
196
 
180
- const bgImage = hasImage ? `
181
- <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_image" translatesAutoresizingMaskIntoConstraints="NO" id="BG">
182
- <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
183
- </imageView>` : '';
184
-
185
- const logoImage = hasLogo ? `
186
- <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_logo" translatesAutoresizingMaskIntoConstraints="NO" id="LOGO">
187
- <rect key="frame" x="132" y="348" width="150" height="150"/>
188
- <constraints>
189
- <constraint firstAttribute="width" constant="150" id="LW"/>
190
- <constraint firstAttribute="height" constant="150" id="LH"/>
191
- </constraints>
192
- </imageView>` : '';
193
-
194
- const bgConstraints = hasImage ? `
195
- <constraint firstItem="BG" firstAttribute="top" secondItem="V" secondAttribute="top" id="BT"/>
196
- <constraint firstItem="BG" firstAttribute="leading" secondItem="V" secondAttribute="leading" id="BL"/>
197
- <constraint firstItem="BG" firstAttribute="trailing" secondItem="V" secondAttribute="trailing" id="BR"/>
198
- <constraint firstItem="BG" firstAttribute="bottom" secondItem="V" secondAttribute="bottom" id="BB"/>` : '';
199
-
200
- const logoConstraints = hasLogo ? `
201
- <constraint firstItem="LOGO" firstAttribute="centerX" secondItem="V" secondAttribute="centerX" id="LX"/>
202
- <constraint firstItem="LOGO" firstAttribute="centerY" secondItem="V" secondAttribute="centerY" id="LY"/>` : '';
203
-
204
- const resources = [];
205
- if (hasImage) resources.push(' <image name="splash_image" width="1242" height="2688"/>');
206
- if (hasLogo) resources.push(' <image name="splash_logo" width="512" height="512"/>');
197
+ // Build subviews
198
+ let subviews = '';
199
+ let constraints = '';
200
+ let resources = '';
201
+
202
+ if (hasImage) {
203
+ subviews += `
204
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SplashImage" translatesAutoresizingMaskIntoConstraints="NO" id="splash-bg">
205
+ <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
206
+ </imageView>`;
207
+
208
+ constraints += `
209
+ <constraint firstItem="splash-bg" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="bg-top"/>
210
+ <constraint firstItem="splash-bg" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="bg-leading"/>
211
+ <constraint firstItem="splash-bg" firstAttribute="trailing" secondItem="Ze5-6b-2t3" secondAttribute="trailing" id="bg-trailing"/>
212
+ <constraint firstItem="splash-bg" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="bg-bottom"/>`;
213
+
214
+ resources += `
215
+ <image name="SplashImage" width="1242" height="2688"/>`;
216
+ }
217
+
218
+ if (hasLogo) {
219
+ subviews += `
220
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SplashLogo" translatesAutoresizingMaskIntoConstraints="NO" id="splash-logo">
221
+ <rect key="frame" x="132" y="373" width="150" height="150"/>
222
+ <constraints>
223
+ <constraint firstAttribute="width" constant="150" id="logo-width"/>
224
+ <constraint firstAttribute="height" constant="150" id="logo-height"/>
225
+ </constraints>
226
+ </imageView>`;
227
+
228
+ constraints += `
229
+ <constraint firstItem="splash-logo" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="logo-centerx"/>
230
+ <constraint firstItem="splash-logo" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="logo-centery"/>`;
231
+
232
+ resources += `
233
+ <image name="SplashLogo" width="512" height="512"/>`;
234
+ }
207
235
 
208
236
  return `<?xml version="1.0" encoding="UTF-8"?>
209
- <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="VC">
237
+ <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
210
238
  <device id="retina6_1" orientation="portrait" appearance="light"/>
211
239
  <dependencies>
212
240
  <deployment identifier="iOS"/>
213
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
241
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
214
242
  <capability name="Safe area layout guides" minToolsVersion="9.0"/>
215
243
  <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
216
244
  </dependencies>
217
245
  <scenes>
218
- <scene sceneID="SC">
246
+ <!--View Controller-->
247
+ <scene sceneID="EHf-IW-A2E">
219
248
  <objects>
220
- <viewController id="VC" sceneMemberID="viewController">
221
- <view key="view" contentMode="scaleToFill" id="V">
249
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
250
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
222
251
  <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
223
252
  <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
224
- <subviews>${bgImage}${logoImage}
253
+ <subviews>${subviews}
225
254
  </subviews>
226
- <viewLayoutGuide key="safeArea" id="SA"/>
255
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
227
256
  <color key="backgroundColor" red="${r}" green="${g}" blue="${b}" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
228
- <constraints>${bgConstraints}${logoConstraints}
257
+ <constraints>${constraints}
229
258
  </constraints>
230
259
  </view>
231
260
  </viewController>
232
- <placeholder placeholderIdentifier="IBFirstResponder" id="FR" userLabel="First Responder" sceneMemberID="firstResponder"/>
261
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
233
262
  </objects>
234
263
  <point key="canvasLocation" x="53" y="375"/>
235
264
  </scene>
236
265
  </scenes>
237
- <resources>${resources.join('\n')}
266
+ <resources>${resources}
238
267
  </resources>
239
268
  </document>`;
240
269
  }