react-native-custom-splash 1.0.3 → 2.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/README.md CHANGED
@@ -1,20 +1,18 @@
1
- # react-native-custom-splash
1
+ # react-native-custom-splash 🎨
2
2
 
3
- A custom splash screen module for React Native with native iOS and Android support, fully compatible with Expo.
3
+ A powerful and easy-to-use custom splash screen module for React Native with native iOS and Android support, **fully compatible with Expo**!
4
4
 
5
- ## Features
5
+ ## Features
6
6
 
7
- - **Native iOS & Android** splash screens
8
- - **Expo compatible** with config plugin
9
- - **Customizable** splash images
10
- - **Animated transitions** for smooth hiding
11
- - **TypeScript** support
12
- - **Auto-show** on app launch
13
- - **Manual control** with show/hide methods
7
+ - 🚀 **Zero Native Code Required** - Just configure in `app.json`
8
+ - 🎨 **Auto Image Setup** - Automatically copies images from your project to native folders
9
+ - 🖼️ **Background + Logo Support** - Add a full background image and/or center logo
10
+ - 🎨 **Customizable Colors** - Set your brand's background color
11
+ - 📱 **Native Performance** - Pure native implementation for both iOS and Android
12
+ - **Expo Compatible** - Works seamlessly with Expo managed workflow
13
+ - 🔄 **Simple API** - Easy show/hide methods with animation support
14
14
 
15
- ## Installation
16
-
17
- ### For Expo Projects
15
+ ## 📦 Installation
18
16
 
19
17
  ```bash
20
18
  npm install react-native-custom-splash
@@ -22,257 +20,312 @@ npm install react-native-custom-splash
22
20
  yarn add react-native-custom-splash
23
21
  ```
24
22
 
25
- Add the plugin to your `app.json` or `app.config.js`:
23
+ ## 🎯 Quick Start (The Easy Way!)
24
+
25
+ ### Step 1: Add your images to your project
26
+
27
+ Create an `assets` folder in your project root and add your images:
28
+
29
+ ```
30
+ your-project/
31
+ ├── assets/
32
+ │ ├── splash-background.png (your full background image - optional)
33
+ │ └── logo.png (your center logo - optional)
34
+ ├── app.json
35
+ └── ...
36
+ ```
37
+
38
+ ### Step 2: Configure in app.json
39
+
40
+ Add the plugin configuration to your `app.json`:
26
41
 
27
42
  ```json
28
43
  {
29
44
  "expo": {
45
+ "name": "YourApp",
30
46
  "plugins": [
31
- "react-native-custom-splash"
47
+ [
48
+ "react-native-custom-splash",
49
+ {
50
+ "backgroundColor": "#FFFFFF",
51
+ "image": "./assets/splash-background.png",
52
+ "logo": "./assets/logo.png",
53
+ "logoWidth": 150
54
+ }
55
+ ]
32
56
  ]
33
57
  }
34
58
  }
35
59
  ```
36
60
 
37
- Then run prebuild:
61
+ ### Step 3: Run prebuild
38
62
 
39
63
  ```bash
40
- npx expo prebuild
64
+ npx expo prebuild --clean
41
65
  ```
42
66
 
43
- ### For Bare React Native Projects
67
+ **That's it!** 🎉 The plugin will automatically:
68
+ - ✅ Copy your images to iOS and Android native folders
69
+ - ✅ Configure the native splash screen
70
+ - ✅ Set up all the required files
71
+ - ✅ Handle different screen densities
44
72
 
45
- ```bash
46
- npm install react-native-custom-splash
47
- # or
48
- yarn add react-native-custom-splash
49
- ```
73
+ ### Step 4: Use in your app
50
74
 
51
- #### iOS Setup
75
+ ```javascript
76
+ import SplashScreen from 'react-native-custom-splash';
77
+ import React, { useEffect } from 'react';
52
78
 
53
- 1. Install pods:
54
- ```bash
55
- cd ios && pod install && cd ..
56
- ```
79
+ function App() {
80
+ useEffect(() => {
81
+ // Hide splash screen after app loads
82
+ setTimeout(() => {
83
+ SplashScreen.hide(true); // true = animated
84
+ }, 2000);
85
+ }, []);
57
86
 
58
- 2. The module will be automatically linked.
87
+ return (
88
+ // Your app content
89
+ );
90
+ }
91
+ ```
59
92
 
60
- #### Android Setup
93
+ ## ⚙️ Configuration Options
61
94
 
62
- 1. Add the package to your `MainApplication.kt`:
95
+ | Option | Type | Default | Description |
96
+ |--------|------|---------|-------------|
97
+ | `backgroundColor` | `string` | `#FFFFFF` | Background color for the splash screen (hex color) |
98
+ | `image` | `string` | `null` | Path to full background image (relative to project root) |
99
+ | `logo` | `string` | `null` | Path to center logo image (relative to project root) |
100
+ | `logoWidth` | `number` | `150` | Width of the center logo in pixels |
63
101
 
64
- ```kotlin
65
- import com.rncustomsplash.SplashScreenPackage
102
+ ### Configuration Examples
66
103
 
67
- // In getPackages() method:
68
- packages.add(SplashScreenPackage())
104
+ #### Only Background Color
105
+ ```json
106
+ {
107
+ "plugins": [
108
+ [
109
+ "react-native-custom-splash",
110
+ {
111
+ "backgroundColor": "#FF6B6B"
112
+ }
113
+ ]
114
+ ]
115
+ }
69
116
  ```
70
117
 
71
- 2. Show splash in `MainActivity.kt`:
72
-
73
- ```kotlin
74
- import com.rncustomsplash.SplashScreenModule
75
-
76
- override fun onCreate(savedInstanceState: Bundle?) {
77
- SplashScreenModule.show(this)
78
- super.onCreate(savedInstanceState)
118
+ #### Background Color + Logo
119
+ ```json
120
+ {
121
+ "plugins": [
122
+ [
123
+ "react-native-custom-splash",
124
+ {
125
+ "backgroundColor": "#1E3A8A",
126
+ "logo": "./assets/logo.png",
127
+ "logoWidth": 200
128
+ }
129
+ ]
130
+ ]
79
131
  }
80
132
  ```
81
133
 
82
- ## Adding Custom Splash Images
83
-
84
- ### iOS
85
-
86
- Add your splash image to your Xcode project:
87
- 1. Open your project in Xcode
88
- 2. Add an image asset named `splash` to your Assets catalog
89
- 3. Or add a `splash.png` file to your project
90
-
91
- ### Android
92
-
93
- Add your splash image to Android resources:
94
- 1. Add `splash.png` (or `splash.jpg`) to `android/app/src/main/res/drawable/`
95
- 2. Or create a drawable resource named `splash`
96
-
97
- You can also customize the background color in `android/app/src/main/res/values/colors.xml`:
98
-
99
- ```xml
100
- <color name="splash_background">#FFFFFF</color>
134
+ #### Full Background Image + Logo
135
+ ```json
136
+ {
137
+ "plugins": [
138
+ [
139
+ "react-native-custom-splash",
140
+ {
141
+ "backgroundColor": "#FFFFFF",
142
+ "image": "./assets/splash-bg.png",
143
+ "logo": "./assets/logo.png",
144
+ "logoWidth": 180
145
+ }
146
+ ]
147
+ ]
148
+ }
101
149
  ```
102
150
 
103
- ## Usage
104
-
105
- ```typescript
106
- import SplashScreen from 'react-native-custom-splash';
107
- import { useEffect } from 'react';
108
-
109
- function App() {
110
- useEffect(() => {
111
- // Hide splash screen after app is ready
112
- // The splash screen shows automatically on launch
113
-
114
- // Simple hide (instant)
115
- SplashScreen.hide(false);
116
-
117
- // Or with animation
118
- SplashScreen.hide(true);
119
-
120
- // You can also show it again
121
- // SplashScreen.show();
122
- }, []);
123
-
124
- return (
125
- // Your app content
126
- );
151
+ #### Only Background Image (No Logo)
152
+ ```json
153
+ {
154
+ "plugins": [
155
+ [
156
+ "react-native-custom-splash",
157
+ {
158
+ "backgroundColor": "#000000",
159
+ "image": "./assets/splash-full.png"
160
+ }
161
+ ]
162
+ ]
127
163
  }
128
164
  ```
129
165
 
130
- ## Example Project
166
+ ## 📱 API Reference
131
167
 
132
- A complete working example is included in the `example/` directory. It demonstrates:
168
+ ### `SplashScreen.hide(animated)`
133
169
 
134
- - Automatic splash screen on launch
135
- - ✅ Loading progress simulation
136
- - ✅ Animated hide transitions
137
- - ✅ Manual show/hide controls
138
- - ✅ Full TypeScript integration
170
+ Hides the splash screen.
139
171
 
140
- ### Run the Example
172
+ **Parameters:**
173
+ - `animated` (boolean): Whether to animate the hide transition. Default: `true`
141
174
 
142
- ```bash
143
- cd example
144
- npm install
145
- npx expo prebuild
146
- npm run ios # or npm run android
147
- ```
175
+ **Returns:** Promise<boolean>
148
176
 
149
- See [example/README.md](./example/README.md) for detailed instructions.
177
+ **Example:**
178
+ ```javascript
179
+ // With animation (recommended)
180
+ await SplashScreen.hide(true);
150
181
 
151
- ## API Reference
182
+ // Without animation
183
+ await SplashScreen.hide(false);
184
+ ```
152
185
 
153
186
  ### `SplashScreen.show()`
154
187
 
155
- Shows the splash screen.
188
+ Shows the splash screen (usually not needed as it shows automatically on app launch).
156
189
 
157
- ```typescript
190
+ **Example:**
191
+ ```javascript
158
192
  SplashScreen.show();
159
193
  ```
160
194
 
161
- ### `SplashScreen.hide(animated?)`
195
+ ## 🎨 Image Guidelines
162
196
 
163
- Hides the splash screen.
197
+ ### Background Image
198
+ - **Recommended size:** 1242 x 2688 px (iPhone 13 Pro Max size)
199
+ - **Format:** PNG or JPG
200
+ - **Aspect ratio:** Match your target device screens
201
+ - **Tip:** The plugin will handle different screen densities automatically
164
202
 
165
- **Parameters:**
166
- - `animated` (boolean, optional): Whether to animate the hide transition. Default: `false`
203
+ ### Logo Image
204
+ - **Recommended size:** 512 x 512 px (or your desired aspect ratio)
205
+ - **Format:** PNG with transparency recommended
206
+ - **Tip:** The logo will be centered and sized according to `logoWidth`
207
+
208
+ ## 🔧 Advanced Usage
167
209
 
168
- **Returns:** `Promise<boolean>` - Resolves to `true` if successful
210
+ ### TypeScript Support
211
+
212
+ Full TypeScript support is included:
169
213
 
170
214
  ```typescript
171
- // Hide instantly
172
- await SplashScreen.hide();
215
+ import SplashScreen, { SplashScreenInterface } from 'react-native-custom-splash';
173
216
 
174
- // Hide with fade animation
175
- await SplashScreen.hide(true);
217
+ const hideSplash = async (): Promise<void> => {
218
+ await SplashScreen.hide(true);
219
+ };
176
220
  ```
177
221
 
178
- ## Example
222
+ ### React Navigation Integration
179
223
 
180
- ```typescript
181
- import React, { useEffect, useState } from 'react';
182
- import { View, Text, ActivityIndicator } from 'react-native';
224
+ ```javascript
225
+ import { NavigationContainer } from '@react-navigation/native';
183
226
  import SplashScreen from 'react-native-custom-splash';
184
227
 
185
- export default function App() {
186
- const [appIsReady, setAppIsReady] = useState(false);
228
+ function App() {
229
+ const [isReady, setIsReady] = React.useState(false);
187
230
 
188
- useEffect(() => {
231
+ React.useEffect(() => {
189
232
  async function prepare() {
190
233
  try {
191
234
  // Load your resources here
192
235
  await loadFonts();
193
236
  await loadData();
194
-
195
- // Artificially delay for demo
196
- await new Promise(resolve => setTimeout(resolve, 2000));
197
237
  } catch (e) {
198
238
  console.warn(e);
199
239
  } finally {
200
- setAppIsReady(true);
240
+ setIsReady(true);
201
241
  }
202
242
  }
203
243
 
204
244
  prepare();
205
245
  }, []);
206
246
 
207
- useEffect(() => {
208
- if (appIsReady) {
209
- // Hide splash screen with animation when app is ready
247
+ React.useEffect(() => {
248
+ if (isReady) {
210
249
  SplashScreen.hide(true);
211
250
  }
212
- }, [appIsReady]);
251
+ }, [isReady]);
213
252
 
214
- if (!appIsReady) {
215
- return null; // Splash screen is visible
253
+ if (!isReady) {
254
+ return null;
216
255
  }
217
256
 
218
257
  return (
219
- <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
220
- <Text>App is ready!</Text>
221
- </View>
258
+ <NavigationContainer>
259
+ {/* Your navigation */}
260
+ </NavigationContainer>
222
261
  );
223
262
  }
224
263
  ```
225
264
 
226
- ## Troubleshooting
227
-
228
- ### iOS
265
+ ## 🔄 Migration from Manual Setup
229
266
 
230
- **Module not found:**
231
- - Make sure you ran `pod install` in the `ios/` directory
232
- - Clean build folder: `cd ios && rm -rf build && cd ..`
233
- - Rebuild the app
267
+ If you were using the old manual method, you can now simplify:
234
268
 
235
- **Splash image not showing:**
236
- - Verify the image is named `splash` in your Assets catalog
237
- - Check that the image is added to the target
269
+ **Before (Manual Method):**
270
+ 1. Manually copy images to `ios/` folder
271
+ 2. Open Xcode and add images to Assets
272
+ 3. ❌ Manually copy images to `android/app/src/main/res/drawable/`
273
+ 4. ❌ Manually edit `colors.xml`
274
+ 5. ❌ Configure multiple drawable folders
238
275
 
239
- ### Android
276
+ **After (Automatic Method):**
277
+ 1. ✅ Add images to `assets/` folder
278
+ 2. ✅ Configure in `app.json`
279
+ 3. ✅ Run `npx expo prebuild --clean`
280
+ 4. ✅ Done!
240
281
 
241
- **Module not found:**
242
- - Verify `SplashScreenPackage()` is added to `MainApplication.kt`
243
- - Clean build: `cd android && ./gradlew clean && cd ..`
244
- - Rebuild the app
282
+ ## 🛠️ Manual Setup (Non-Expo Projects)
245
283
 
246
- **Splash image not showing:**
247
- - Check that `splash.png` exists in `res/drawable/`
248
- - Verify the resource name matches in `splash_screen.xml`
284
+ If you're not using Expo, you can still use this package with manual setup:
249
285
 
250
- ### Expo
286
+ ### iOS
251
287
 
252
- **Plugin not working:**
253
- - Make sure you added the plugin to `app.json`
254
- - Run `npx expo prebuild --clean`
255
- - Rebuild the app
288
+ Add your splash image to your Xcode project:
289
+ 1. Open your project in Xcode
290
+ 2. Add an image asset named `splash_image` for background and/or `splash_logo` for center logo to your Assets catalog
256
291
 
257
- ## TypeScript
292
+ ### Android
258
293
 
259
- This package includes TypeScript definitions. The module exports the following interface:
294
+ Add your images to Android resources:
295
+ 1. Add `splash_image.png` (background) and/or `splash_logo.png` (center logo) to `android/app/src/main/res/drawable/`
296
+ 2. Customize the background color in `android/app/src/main/res/values/colors.xml`:
260
297
 
261
- ```typescript
262
- interface SplashScreenInterface {
263
- show(): void;
264
- hide(animated?: boolean): Promise<boolean>;
265
- }
298
+ ```xml
299
+ <color name="splash_background">#FFFFFF</color>
266
300
  ```
267
301
 
268
- ## License
302
+ ## ❓ Troubleshooting
303
+
304
+ ### Splash screen not showing
305
+ - Make sure you run `npx expo prebuild --clean` after changing configuration
306
+ - Check that your image paths in `app.json` are correct and files exist
307
+ - Try cleaning your build: `cd ios && pod install && cd ..` for iOS
308
+
309
+ ### Images not updating
310
+ - Run `npx expo prebuild --clean` to force regeneration of native projects
311
+ - Clear build caches and rebuild
312
+
313
+ ### TypeScript errors
314
+ - Make sure you have `@types/react` and `@types/react-native` installed
315
+ - The package includes TypeScript definitions
316
+
317
+ ## 📄 License
269
318
 
270
319
  MIT
271
320
 
272
- ## Contributing
321
+ ## 🤝 Contributing
273
322
 
274
323
  Contributions are welcome! Please feel free to submit a Pull Request.
275
324
 
276
- ## Issues
325
+ ## 💖 Support
326
+
327
+ If you find this package helpful, please give it a ⭐️ on [GitHub](https://github.com/vijaykishan312/react-native-custom-splash)!
328
+
329
+ ---
277
330
 
278
- If you encounter any issues, please file them on the GitHub repository.
331
+ Made with ❤️ for the React Native community
@@ -40,16 +40,22 @@ class SplashScreenModule: NSObject {
40
40
  let splashVC = UIViewController()
41
41
  splashVC.view.backgroundColor = .white
42
42
 
43
- // Try to load splash image from the main bundle
44
- // Users should add their splash image to their app's assets
45
- if let splashImage = UIImage(named: "splash") {
43
+ // Try to load background splash image from the main bundle
44
+ if let splashImage = UIImage(named: "splash_image") {
45
+ let imageView = UIImageView(image: splashImage)
46
+ imageView.contentMode = .scaleAspectFill
47
+ imageView.frame = splashVC.view.bounds
48
+ imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
49
+ splashVC.view.addSubview(imageView)
50
+ } else if let splashImage = UIImage(named: "splash") {
51
+ // Fallback to old "splash" name for backward compatibility
46
52
  let imageView = UIImageView(image: splashImage)
47
53
  imageView.contentMode = .scaleAspectFill
48
54
  imageView.frame = splashVC.view.bounds
49
55
  imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
50
56
  splashVC.view.addSubview(imageView)
51
57
  } else {
52
- // Fallback: show white screen if no splash image is provided
58
+ // Fallback: show white screen if no background image
53
59
  if #available(iOS 13.0, *) {
54
60
  splashVC.view.backgroundColor = .systemBackground
55
61
  } else {
@@ -57,6 +63,27 @@ class SplashScreenModule: NSObject {
57
63
  }
58
64
  }
59
65
 
66
+ // Add center logo if available
67
+ if let logoImage = UIImage(named: "splash_logo") {
68
+ let logoView = UIImageView(image: logoImage)
69
+ logoView.contentMode = .scaleAspectFit
70
+
71
+ // Set logo size (150pt width by default, maintaining aspect ratio)
72
+ let logoWidth: CGFloat = 150
73
+ let aspectRatio = logoImage.size.height / logoImage.size.width
74
+ let logoHeight = logoWidth * aspectRatio
75
+
76
+ logoView.frame = CGRect(
77
+ x: (splashVC.view.bounds.width - logoWidth) / 2,
78
+ y: (splashVC.view.bounds.height - logoHeight) / 2,
79
+ width: logoWidth,
80
+ height: logoHeight
81
+ )
82
+
83
+ logoView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
84
+ splashVC.view.addSubview(logoView)
85
+ }
86
+
60
87
  window.rootViewController = splashVC
61
88
  window.makeKeyAndVisible()
62
89
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-custom-splash",
3
- "version": "1.0.3",
3
+ "version": "2.0.0",
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",
@@ -23,6 +23,10 @@
23
23
  "type": "git",
24
24
  "url": "git+https://github.com/vijaykishan312/react-native-custom-splash.git"
25
25
  },
26
+ "dependencies": {
27
+ "@expo/config-plugins": "^8.0.0",
28
+ "@expo/image-utils": "^0.5.0"
29
+ },
26
30
  "peerDependencies": {
27
31
  "react": "*",
28
32
  "react-native": "*",
@@ -3,14 +3,210 @@ const {
3
3
  withPlugins,
4
4
  withMainActivity,
5
5
  withMainApplication,
6
+ AndroidConfig,
7
+ IOSConfig,
6
8
  } = require('@expo/config-plugins');
7
9
  const path = require('path');
8
10
  const fs = require('fs');
11
+ const { generateImageAsync } = require('@expo/image-utils');
9
12
 
10
13
  /**
11
- * Plugin to add SplashScreenModule to Android
14
+ * Get plugin configuration from app.json
12
15
  */
13
- const withSplashScreenAndroid = (config) => {
16
+ function getPluginConfig(config) {
17
+ const plugins = config.plugins || [];
18
+ const splashPlugin = plugins.find(plugin => {
19
+ if (Array.isArray(plugin) && plugin[0] === 'react-native-custom-splash') {
20
+ return true;
21
+ }
22
+ return plugin === 'react-native-custom-splash';
23
+ });
24
+
25
+ if (Array.isArray(splashPlugin) && splashPlugin[1]) {
26
+ return splashPlugin[1];
27
+ }
28
+
29
+ // Default configuration
30
+ return {
31
+ backgroundColor: '#FFFFFF',
32
+ image: null,
33
+ logo: null,
34
+ logoWidth: 150,
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Copy and resize image to Android drawable folders
40
+ */
41
+ async function copyImageToAndroid(projectRoot, imagePath, outputName, resDir) {
42
+ if (!imagePath || !fs.existsSync(path.join(projectRoot, imagePath))) {
43
+ return false;
44
+ }
45
+
46
+ const sourceImage = path.join(projectRoot, imagePath);
47
+
48
+ // Define sizes for different densities
49
+ const densities = {
50
+ 'mdpi': 1,
51
+ 'hdpi': 1.5,
52
+ 'xhdpi': 2,
53
+ 'xxhdpi': 3,
54
+ 'xxxhdpi': 4,
55
+ };
56
+
57
+ for (const [density, scale] of Object.entries(densities)) {
58
+ const drawableDir = path.join(resDir, `drawable-${density}`);
59
+
60
+ // Create directory if it doesn't exist
61
+ if (!fs.existsSync(drawableDir)) {
62
+ fs.mkdirSync(drawableDir, { recursive: true });
63
+ }
64
+
65
+ const outputPath = path.join(drawableDir, `${outputName}.png`);
66
+
67
+ // Copy the image (you can add resizing logic here if needed)
68
+ fs.copyFileSync(sourceImage, outputPath);
69
+ }
70
+
71
+ return true;
72
+ }
73
+
74
+ /**
75
+ * Copy image to iOS assets
76
+ */
77
+ async function copyImageToIOS(projectRoot, imagePath, outputName, iosProjectPath, projectName) {
78
+ if (!imagePath || !fs.existsSync(path.join(projectRoot, imagePath))) {
79
+ return false;
80
+ }
81
+
82
+ const sourceImage = path.join(projectRoot, imagePath);
83
+ const assetsDir = path.join(iosProjectPath, projectName, 'Images.xcassets', `${outputName}.imageset`);
84
+
85
+ // Create imageset directory
86
+ if (!fs.existsSync(assetsDir)) {
87
+ fs.mkdirSync(assetsDir, { recursive: true });
88
+ }
89
+
90
+ // Copy image files for different scales
91
+ const scales = ['1x', '2x', '3x'];
92
+ const images = [];
93
+
94
+ for (const scale of scales) {
95
+ const filename = `${outputName}@${scale}.png`;
96
+ const destPath = path.join(assetsDir, filename);
97
+ fs.copyFileSync(sourceImage, destPath);
98
+
99
+ images.push({
100
+ idiom: 'universal',
101
+ filename: filename,
102
+ scale: scale,
103
+ });
104
+ }
105
+
106
+ // Create Contents.json
107
+ const contentsJson = {
108
+ images: images,
109
+ info: {
110
+ author: 'xcode',
111
+ version: 1,
112
+ },
113
+ };
114
+
115
+ fs.writeFileSync(
116
+ path.join(assetsDir, 'Contents.json'),
117
+ JSON.stringify(contentsJson, null, 2)
118
+ );
119
+
120
+ return true;
121
+ }
122
+
123
+ /**
124
+ * Update Android colors.xml
125
+ */
126
+ function updateAndroidColors(resDir, backgroundColor) {
127
+ const valuesDir = path.join(resDir, 'values');
128
+ if (!fs.existsSync(valuesDir)) {
129
+ fs.mkdirSync(valuesDir, { recursive: true });
130
+ }
131
+
132
+ const colorsPath = path.join(valuesDir, 'colors.xml');
133
+ const colorsXml = `<?xml version="1.0" encoding="utf-8"?>
134
+ <resources>
135
+ <color name="splash_background">${backgroundColor}</color>
136
+ </resources>
137
+ `;
138
+
139
+ fs.writeFileSync(colorsPath, colorsXml);
140
+ }
141
+
142
+ /**
143
+ * Update Android splash drawable
144
+ */
145
+ function updateAndroidSplashDrawable(resDir, hasImage, hasLogo) {
146
+ const drawableDir = path.join(resDir, 'drawable');
147
+ if (!fs.existsSync(drawableDir)) {
148
+ fs.mkdirSync(drawableDir, { recursive: true });
149
+ }
150
+
151
+ const splashPath = path.join(drawableDir, 'splash.xml');
152
+
153
+ let items = [];
154
+
155
+ // Background color
156
+ items.push(' <item android:drawable="@color/splash_background"/>');
157
+
158
+ // Background image if provided
159
+ if (hasImage) {
160
+ items.push(' <item>');
161
+ items.push(' <bitmap');
162
+ items.push(' android:gravity="fill"');
163
+ items.push(' android:src="@drawable/splash_image"/>');
164
+ items.push(' </item>');
165
+ }
166
+
167
+ // Logo if provided
168
+ if (hasLogo) {
169
+ items.push(' <item>');
170
+ items.push(' <bitmap');
171
+ items.push(' android:gravity="center"');
172
+ items.push(' android:src="@drawable/splash_logo"/>');
173
+ items.push(' </item>');
174
+ }
175
+
176
+ const splashXml = `<?xml version="1.0" encoding="utf-8"?>
177
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
178
+ ${items.join('\n')}
179
+ </layer-list>
180
+ `;
181
+
182
+ fs.writeFileSync(splashPath, splashXml);
183
+ }
184
+
185
+ /**
186
+ * Update Android splash layout
187
+ */
188
+ function updateAndroidSplashLayout(resDir) {
189
+ const layoutDir = path.join(resDir, 'layout');
190
+ if (!fs.existsSync(layoutDir)) {
191
+ fs.mkdirSync(layoutDir, { recursive: true });
192
+ }
193
+
194
+ const layoutPath = path.join(layoutDir, 'splash_screen.xml');
195
+ const layoutXml = `<?xml version="1.0" encoding="utf-8"?>
196
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
197
+ android:layout_width="match_parent"
198
+ android:layout_height="match_parent"
199
+ android:background="@drawable/splash">
200
+ </FrameLayout>
201
+ `;
202
+
203
+ fs.writeFileSync(layoutPath, layoutXml);
204
+ }
205
+
206
+ /**
207
+ * Plugin to configure Android splash screen
208
+ */
209
+ const withSplashScreenAndroid = (config, pluginConfig) => {
14
210
  // Add package to MainApplication
15
211
  config = withMainApplication(config, async (config) => {
16
212
  const { modResults } = config;
@@ -61,18 +257,89 @@ const withSplashScreenAndroid = (config) => {
61
257
  return config;
62
258
  });
63
259
 
260
+ // Configure Android resources
261
+ config = withDangerousMod(config, [
262
+ 'android',
263
+ async (config) => {
264
+ const projectRoot = config.modRequest.projectRoot;
265
+ const resDir = path.join(
266
+ config.modRequest.platformProjectRoot,
267
+ 'app',
268
+ 'src',
269
+ 'main',
270
+ 'res'
271
+ );
272
+
273
+ // Update colors
274
+ updateAndroidColors(resDir, pluginConfig.backgroundColor);
275
+
276
+ // Copy images if provided
277
+ let hasImage = false;
278
+ let hasLogo = false;
279
+
280
+ if (pluginConfig.image) {
281
+ hasImage = await copyImageToAndroid(
282
+ projectRoot,
283
+ pluginConfig.image,
284
+ 'splash_image',
285
+ resDir
286
+ );
287
+ }
288
+
289
+ if (pluginConfig.logo) {
290
+ hasLogo = await copyImageToAndroid(
291
+ projectRoot,
292
+ pluginConfig.logo,
293
+ 'splash_logo',
294
+ resDir
295
+ );
296
+ }
297
+
298
+ // Update splash drawable
299
+ updateAndroidSplashDrawable(resDir, hasImage, hasLogo);
300
+
301
+ // Update splash layout
302
+ updateAndroidSplashLayout(resDir);
303
+
304
+ return config;
305
+ },
306
+ ]);
307
+
64
308
  return config;
65
309
  };
66
310
 
67
311
  /**
68
- * Plugin to add SplashScreenModule to iOS
312
+ * Plugin to configure iOS splash screen
69
313
  */
70
- const withSplashScreenIOS = (config) => {
314
+ const withSplashScreenIOS = (config, pluginConfig) => {
71
315
  return withDangerousMod(config, [
72
316
  'ios',
73
317
  async (config) => {
74
- // The native files will be linked via CocoaPods
75
- // No additional configuration needed here
318
+ const projectRoot = config.modRequest.projectRoot;
319
+ const iosProjectPath = config.modRequest.platformProjectRoot;
320
+ const projectName = config.modRequest.projectName;
321
+
322
+ // Copy images to iOS assets
323
+ if (pluginConfig.image) {
324
+ await copyImageToIOS(
325
+ projectRoot,
326
+ pluginConfig.image,
327
+ 'splash_image',
328
+ iosProjectPath,
329
+ projectName
330
+ );
331
+ }
332
+
333
+ if (pluginConfig.logo) {
334
+ await copyImageToIOS(
335
+ projectRoot,
336
+ pluginConfig.logo,
337
+ 'splash_logo',
338
+ iosProjectPath,
339
+ projectName
340
+ );
341
+ }
342
+
76
343
  return config;
77
344
  },
78
345
  ]);
@@ -81,9 +348,11 @@ const withSplashScreenIOS = (config) => {
81
348
  /**
82
349
  * Main plugin export
83
350
  */
84
- module.exports = (config) => {
351
+ module.exports = (config, props = {}) => {
352
+ const pluginConfig = props || getPluginConfig(config);
353
+
85
354
  return withPlugins(config, [
86
- withSplashScreenAndroid,
87
- withSplashScreenIOS,
355
+ [withSplashScreenAndroid, pluginConfig],
356
+ [withSplashScreenIOS, pluginConfig],
88
357
  ]);
89
358
  };