@sekizlipenguen/react-native-splash-helper 0.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/README.md ADDED
@@ -0,0 +1,158 @@
1
+ ![platforms](https://img.shields.io/badge/platforms-Android%20%7C%20iOS-brightgreen.svg?style=flat-square&colorB=191A17)
2
+ [![npm](https://img.shields.io/npm/v/@sekizlipenguen/react-native-splash-helper.svg?style=flat-square)](https://www.npmjs.com/package/@sekizlipenguen/react-native-splash-helper)
3
+ [![npm](https://img.shields.io/npm/dm/@sekizlipenguen/react-native-splash-helper.svg?style=flat-square&colorB=007ec6)](https://www.npmjs.com/package/@sekizlipenguen/react-native-splash-helper)
4
+
5
+
6
+ # @sekizlipenguen/react-native-splash-helper
7
+
8
+ A lightweight React Native library to automatically configure splash screens for both Android and iOS platforms. Simplifies the splash screen setup process for developers.
9
+
10
+ ## Features
11
+
12
+ - **Automatic Splash Screen Setup**: Configures splash screens for both Android and iOS with minimal setup.
13
+ - **Theme Detection**: Automatically detects application and activity themes in `AndroidManifest.xml`.
14
+ - **Cross-Platform Support**: Works seamlessly on macOS, Linux, and Windows.
15
+ - **Customizable**: Easily define splash image and background color through a simple configuration.
16
+
17
+ ---
18
+
19
+ ## Installation
20
+
21
+ Install the library using Yarn or npm:
22
+
23
+ YARN
24
+ ```bash
25
+ yarn add @sekizlipenguen/react-native-splash-helper --dev
26
+ ```
27
+ NPM
28
+ ```bash
29
+ npm install @sekizlipenguen/react-native-splash-helper --save-dev
30
+ ```
31
+
32
+
33
+ > Note: The `xml2js` package is included as a dependency and used internally.
34
+
35
+ ---
36
+
37
+ ## Configuration
38
+
39
+ ### Configuration Options
40
+
41
+ | Option | Platform | Type | Description |
42
+ |-------------------------|----------|----------|------------------------------------------------------------------------|
43
+ | `splashImage` | Both | `string` | Path to the splash image file. |
44
+ | `backgroundColor` | Android | `string` | Background color in HEX format (e.g., `#ffffff`). |
45
+
46
+ To configure the splash helper, add a section to your `react-native.config.js` file:
47
+
48
+ ```javascript
49
+ module.exports = {
50
+ dependencies: {},
51
+ '@sekizlipenguen/react-native-splash-helper': {
52
+ android: {
53
+ splashImage: './assets/splash_image.png' // Path to your splash image
54
+ },
55
+ ios: {
56
+ splashImage: './assets/splash_image.png' // Path to your splash image
57
+ }
58
+ }
59
+ };
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Usage
65
+
66
+ Run the following command to generate the splash screens:
67
+
68
+ ```bash
69
+ npx @sekizlipenguen/react-native-splash-helper generate-splash
70
+ ```
71
+
72
+ ---
73
+
74
+ ## What It Does
75
+
76
+ 1. **Android**:
77
+
78
+ - Updates `styles.xml` to include the `android:windowBackground` property for detected themes.
79
+ - Updates or creates `colors.xml` with the specified background color.
80
+ - Generates the drawable resource for the splash screen.
81
+ - Updates the `AndroidManifest.xml` to ensure consistency in theme configuration.
82
+
83
+ 2. **iOS**:
84
+
85
+ - Updates the `LaunchScreen.storyboard` file with the splash image and background color.
86
+ - Creates the necessary image assets in the `Images.xcassets` directory.
87
+
88
+ ---
89
+
90
+ ## Example
91
+
92
+ ### Android Output
93
+
94
+ - Updates the following in `styles.xml`:
95
+ ```xml
96
+ <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
97
+ <item name="android:windowBackground">@drawable/splash_background</item>
98
+ </style>
99
+ ```
100
+ - Updates or creates `colors.xml`:
101
+ ```xml
102
+ <resources>
103
+ <color name="splash_background">#ffffff</color>
104
+ </resources>
105
+ ```
106
+ - Creates `splash_background.xml` in `drawable`:
107
+ ```xml
108
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
109
+ <item android:drawable="@color/splash_background" />
110
+ <item>
111
+ <bitmap android:gravity="fill" android:src="@drawable/splash_image" />
112
+ </item>
113
+ </layer-list>
114
+ ```
115
+
116
+ ### iOS Output
117
+
118
+ - Updates `LaunchScreen.storyboard` with:
119
+ ```xml
120
+ <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" ...>
121
+ <scene>
122
+ ...
123
+ <view key="view" contentMode="scaleToFill">
124
+ <color key="backgroundColor" systemColor="systemBackgroundColor" />
125
+ <subviews>
126
+ <imageView contentMode="scaleAspectFill" image="splash_image" ... />
127
+ </subviews>
128
+ </view>
129
+ </scene>
130
+ </document>
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Screenshots
136
+
137
+ ### Splash Screen Example
138
+ ![Android Splash Screen](assets/splash_1.webp)
139
+ ---
140
+
141
+ ## Notes
142
+
143
+ - Make sure your splash image is available at the specified path.
144
+ - If any required file (e.g., `styles.xml`, `colors.xml`) does not exist, it will be created automatically.
145
+ - The script is non-destructive and will not overwrite existing configurations unless necessary.
146
+
147
+ ---
148
+
149
+ ## Contributing
150
+
151
+ Contributions are welcome! Please submit an issue or pull request on the [GitHub repository](https://github.com/sekizlipenguen/react-native-splash-helper).
152
+
153
+ ---
154
+
155
+ ## License
156
+
157
+ MIT © [Sekizli Penguen](https://github.com/sekizlipenguen)
158
+
Binary file
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const generateSplash = require(path.join(__dirname, '../scripts/generateSplash'));
5
+
6
+ generateSplash();
package/index.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ // Splash konfigürasyonu tiplerini tanımlıyoruz
2
+ export interface AndroidConfig {
3
+ backgroundColor: string; // Hex renk kodu (#FFFFFF gibi)
4
+ splashImage: string; // Splash görselinin yolu
5
+ }
6
+
7
+ export interface IOSConfig {
8
+ backgroundColor: string; // Hex renk kodu
9
+ splashImage: string; // Splash görselinin yolu
10
+ }
11
+
12
+ export interface SplashConfig {
13
+ android?: AndroidConfig;
14
+ ios?: IOSConfig;
15
+ }
16
+
17
+ // Komut tipi
18
+ export interface Command {
19
+ name: string; // Komutun adı
20
+ description: string; // Komut açıklaması
21
+ func: (config?: SplashConfig) => void; // Komutun çalıştırdığı fonksiyon
22
+ }
23
+
24
+ // Modül tanımı
25
+ declare const commands: Command[];
26
+
27
+ export default commands;
package/index.js ADDED
@@ -0,0 +1,11 @@
1
+ const generateSplash = require('./scripts/generateSplash');
2
+
3
+ module.exports = {
4
+ commands: [
5
+ {
6
+ name: 'generate-splash',
7
+ description: 'Generates splash screen assets for iOS and Android',
8
+ func: generateSplash,
9
+ },
10
+ ],
11
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@sekizlipenguen/react-native-splash-helper",
3
+ "version": "0.0.1",
4
+ "description": "A lightweight React Native library to automatically configure splash screens for both Android and iOS platforms. Simplifies the splash screen setup process for React Native developers.",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "author": "Sekizli Penguen (https://github.com/sekizlipenguen)",
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/sekizlipenguen/react-native-splash-helper#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/sekizlipenguen/react-native-splash-helper.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/sekizlipenguen/react-native-splash-helper/issues"
16
+ },
17
+ "peerDependencies": {
18
+ "react-native": ">=0.60"
19
+ },
20
+ "dependencies": {
21
+ "xml2js": "^0.4.23"
22
+ },
23
+ "scripts": {
24
+ "postinstall": "node scripts/cleanBin.js"
25
+ },
26
+ "bin": {
27
+ "@sekizlipenguen/react-native-splash-helper": "./bin/react-native-splash-helper"
28
+ },
29
+ "keywords": [
30
+ "react-native",
31
+ "splash-screen",
32
+ "react-native-splash",
33
+ "android-splash-screen",
34
+ "ios-splash-screen",
35
+ "react-native-library",
36
+ "native-module",
37
+ "automated-splash-screen",
38
+ "react-native-splash-helper"
39
+ ]
40
+ }
@@ -0,0 +1,24 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { execSync } = require('child_process');
4
+
5
+ // Bin dizinindeki dosyanın yolunu belirle
6
+ const binPath = path.join(process.cwd(), 'node_modules/.bin/react-native-splash-helper');
7
+
8
+ try {
9
+ // Eğer dosya mevcutsa, önce sil
10
+ if (fs.existsSync(binPath)) {
11
+ fs.unlinkSync(binPath);
12
+ console.log('Removed old bin file: react-native-splash-helper');
13
+ }
14
+
15
+ // Yeni dosya oluşturulmadan önce izinleri ayarla
16
+ const newBinPath = path.join(process.cwd(), 'bin/react-native-splash-helper');
17
+ if (fs.existsSync(newBinPath)) {
18
+ // Yeni dosya kopyalanmadan önce izinleri kontrol et ve düzenle
19
+ execSync(`chmod +x ${newBinPath}`);
20
+ console.log('Updated permissions for: react-native-splash-helper');
21
+ }
22
+ } catch (error) {
23
+ console.error(`Error during cleanBin operation: ${error.message}`);
24
+ }
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+
3
+ const updateStyles = require('./updateStyles');
4
+ const updateStoryboard = require('./updateStoryboard');
5
+
6
+ async function generateSplash() {
7
+ console.log('Generating splash screens...');
8
+
9
+ try {
10
+ // React Native config dosyasını yükle
11
+ const config = require(`${process.cwd()}/react-native.config.js`)['@sekizlipenguen/react-native-splash-helper'];
12
+
13
+ if (!config) {
14
+ console.error(
15
+ 'Splash configuration not found in react-native.config.js. Please add the required configuration.'
16
+ );
17
+ process.exit(1);
18
+ }
19
+
20
+ // Android işlemleri
21
+ if (config.android) {
22
+ try {
23
+ await updateStyles(config.android); // Android için splash ekranını oluştur
24
+ console.log('Android splash screen setup completed.');
25
+ } catch (error) {
26
+ console.error('Error generating Android splash screen:', error.message);
27
+ }
28
+ } else {
29
+ console.log('No Android configuration found. Skipping Android splash screen setup.');
30
+ }
31
+
32
+ // iOS işlemleri
33
+ if (config.ios) {
34
+ try {
35
+ updateStoryboard(config.ios); // iOS için splash ekranını oluştur
36
+ console.log('iOS splash screen setup completed.');
37
+ } catch (error) {
38
+ console.error('Error generating iOS splash screen:', error.message);
39
+ }
40
+ } else {
41
+ console.log('No iOS configuration found. Skipping iOS splash screen setup.');
42
+ }
43
+
44
+ console.log('Splash screens have been successfully generated!');
45
+ } catch (error) {
46
+ console.error('Error during splash screen generation:', error.message);
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ module.exports = generateSplash;
@@ -0,0 +1,97 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ function updateStoryboard(iosConfig) {
5
+ const iosAppName = fs
6
+ .readdirSync(path.join(process.cwd(), 'ios'))
7
+ .find((dir) => fs.existsSync(path.join(process.cwd(), 'ios', dir, 'Info.plist')));
8
+
9
+ if (!iosAppName) {
10
+ console.error('iOS app name could not be resolved.');
11
+ return;
12
+ }
13
+
14
+ const storyboardPath = path.join(process.cwd(), `ios/${iosAppName}/LaunchScreen.storyboard`);
15
+ const assetsPath = path.join(process.cwd(), `ios/${iosAppName}/Images.xcassets`);
16
+ const splashImagePath = path.join(assetsPath, 'splash_image.imageset');
17
+
18
+ // Assets ve splash image için dizinler oluşturuluyor
19
+ if (!fs.existsSync(assetsPath)) {
20
+ fs.mkdirSync(assetsPath, { recursive: true });
21
+ }
22
+ if (!fs.existsSync(splashImagePath)) {
23
+ fs.mkdirSync(splashImagePath, { recursive: true });
24
+ }
25
+
26
+ // Splash görseli kopyalanıyor
27
+ const splashImageSource = path.resolve(iosConfig.splashImage);
28
+ const splashImageTarget = path.join(splashImagePath, 'splash_image.png');
29
+ fs.copyFileSync(splashImageSource, splashImageTarget);
30
+
31
+ // Contents.json dosyasını oluştur
32
+ const contentsJson = {
33
+ images: [
34
+ { idiom: 'universal', filename: 'splash_image.png', scale: '1x' },
35
+ { idiom: 'universal', filename: 'splash_image.png', scale: '2x' },
36
+ { idiom: 'universal', filename: 'splash_image.png', scale: '3x' },
37
+ ],
38
+ info: { version: 1, author: 'xcode' },
39
+ };
40
+ fs.writeFileSync(
41
+ path.join(splashImagePath, 'Contents.json'),
42
+ JSON.stringify(contentsJson, null, 2),
43
+ 'utf8'
44
+ );
45
+
46
+ // Storyboard içeriği
47
+ const storyboardContent = `<?xml version="1.0" encoding="UTF-8"?>
48
+ <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
49
+ <device id="retina4_7" orientation="portrait" appearance="light"/>
50
+ <dependencies>
51
+ <deployment identifier="iOS"/>
52
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
53
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
54
+ <capability name="System colors in document resources" minToolsVersion="11.0"/>
55
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
56
+ </dependencies>
57
+ <scenes>
58
+ <!--View Controller-->
59
+ <scene sceneID="EHf-IW-A2E">
60
+ <objects>
61
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
62
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
63
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
64
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
65
+ <subviews>
66
+ <imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" image="splash_image" translatesAutoresizingMaskIntoConstraints="NO" id="img-splash">
67
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
68
+ </imageView>
69
+ </subviews>
70
+ <viewLayoutGuide key="safeArea" id="jCx-lo-f50"/>
71
+ <color key="backgroundColor" systemColor="systemBackgroundColor"/>
72
+ <constraints>
73
+ <constraint firstItem="img-splash" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="bottom-constraint"/>
74
+ <constraint firstItem="img-splash" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="leading-constraint"/>
75
+ <constraint firstItem="img-splash" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="top-constraint"/>
76
+ <constraint firstItem="img-splash" firstAttribute="trailing" secondItem="Ze5-6b-2t3" secondAttribute="trailing" id="trailing-constraint"/>
77
+ </constraints>
78
+ </view>
79
+ </viewController>
80
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
81
+ </objects>
82
+ <point key="canvasLocation" x="52.173913043478265" y="375"/>
83
+ </scene>
84
+ </scenes>
85
+ <resources>
86
+ <image name="splash_image" width="645" height="1398"/>
87
+ <systemColor name="systemBackgroundColor">
88
+ <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
89
+ </systemColor>
90
+ </resources>
91
+ </document>`;
92
+
93
+ fs.writeFileSync(storyboardPath, storyboardContent, 'utf8');
94
+ console.log('LaunchScreen.storyboard updated successfully.');
95
+ }
96
+
97
+ module.exports = updateStoryboard;
@@ -0,0 +1,125 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { parseStringPromise, Builder } = require('xml2js');
4
+
5
+ async function updateStyles(androidConfig) {
6
+ const stylesPath = path.join(process.cwd(), 'android/app/src/main/res/values/styles.xml');
7
+ const colorsPath = path.join(process.cwd(), 'android/app/src/main/res/values/colors.xml');
8
+ const manifestPath = path.join(process.cwd(), 'android/app/src/main/AndroidManifest.xml');
9
+ const drawablePath = path.join(process.cwd(), 'android/app/src/main/res/drawable');
10
+ const splashImageSource = path.resolve(androidConfig.splashImage);
11
+
12
+ // ** Retrieve theme name from AndroidManifest.xml **
13
+ if (!fs.existsSync(manifestPath)) {
14
+ console.error('AndroidManifest.xml not found. Please check the path.');
15
+ return;
16
+ }
17
+
18
+ const manifestContent = fs.readFileSync(manifestPath, 'utf8');
19
+ const manifestJson = await parseStringPromise(manifestContent);
20
+
21
+ const applicationNode = manifestJson.manifest.application[0];
22
+ const themeAttribute = applicationNode.$['android:theme'];
23
+ const mainActivityNode = applicationNode.activity.find(
24
+ (activity) => activity.$['android:name'] === '.MainActivity'
25
+ );
26
+
27
+ if (!themeAttribute) {
28
+ console.error('No theme found in AndroidManifest.xml at the application level.');
29
+ return;
30
+ }
31
+
32
+ const appThemeName = themeAttribute.replace('@style/', '');
33
+ console.log(`Using application theme: ${appThemeName}`);
34
+
35
+ let mainActivityThemeName = null;
36
+ if (mainActivityNode && mainActivityNode.$['android:theme']) {
37
+ mainActivityThemeName = mainActivityNode.$['android:theme'].replace('@style/', '');
38
+ console.log(`Using MainActivity theme: ${mainActivityThemeName}`);
39
+ }
40
+
41
+ const themeNames = [appThemeName, mainActivityThemeName].filter(Boolean);
42
+
43
+ // ** Update styles.xml **
44
+ if (fs.existsSync(stylesPath)) {
45
+ const stylesContent = fs.readFileSync(stylesPath, 'utf8');
46
+ const stylesJson = await parseStringPromise(stylesContent);
47
+
48
+ themeNames.forEach((themeName) => {
49
+ const appTheme = stylesJson.resources.style.find((style) => style.$.name === themeName);
50
+ if (appTheme && !appTheme.item.some((item) => item.$.name === 'android:windowBackground')) {
51
+ appTheme.item.push({ $: { name: 'android:windowBackground' }, _: '@drawable/splash_background' });
52
+ console.log(`Added android:windowBackground to theme: ${themeName}`);
53
+ }
54
+ });
55
+
56
+ const updatedStylesContent = new Builder().buildObject(stylesJson);
57
+ fs.writeFileSync(stylesPath, updatedStylesContent, 'utf8');
58
+ console.log('styles.xml updated.');
59
+ } else {
60
+ console.error('styles.xml not found. Please check the path.');
61
+ return;
62
+ }
63
+
64
+ // ** Update colors.xml **
65
+ let colorsJson;
66
+ if (fs.existsSync(colorsPath)) {
67
+ const colorsContent = fs.readFileSync(colorsPath, 'utf8') || '<resources></resources>';
68
+ colorsJson = await parseStringPromise(colorsContent);
69
+
70
+ if (typeof colorsJson.resources === 'string') {
71
+ colorsJson.resources = {};
72
+ }
73
+
74
+ if (!colorsJson.resources.color) {
75
+ colorsJson.resources.color = [];
76
+ }
77
+
78
+ const splashColor = colorsJson.resources.color.find((color) => color.$.name === 'splash_background');
79
+ if (splashColor) {
80
+ splashColor._ = androidConfig.backgroundColor;
81
+ } else {
82
+ colorsJson.resources.color.push({
83
+ $: { name: 'splash_background' },
84
+ _: androidConfig.backgroundColor,
85
+ });
86
+ }
87
+ } else {
88
+ console.log('colors.xml not found. Creating a new colors.xml file.');
89
+ colorsJson = {
90
+ resources: {
91
+ color: [
92
+ {
93
+ $: { name: 'splash_background' },
94
+ _: androidConfig.backgroundColor,
95
+ },
96
+ ],
97
+ },
98
+ };
99
+ }
100
+
101
+ const updatedColorsContent = new Builder().buildObject(colorsJson);
102
+ fs.writeFileSync(colorsPath, updatedColorsContent, 'utf8');
103
+ console.log('colors.xml created or updated.');
104
+
105
+ // ** Update Drawable Splash **
106
+ if (!fs.existsSync(drawablePath)) {
107
+ fs.mkdirSync(drawablePath, { recursive: true });
108
+ }
109
+
110
+ const splashDrawableContent = `
111
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
112
+ <item android:drawable="@color/splash_background" />
113
+ <item>
114
+ <bitmap android:gravity="fill" android:src="@drawable/splash_image" />
115
+ </item>
116
+ </layer-list>
117
+ `;
118
+
119
+ const splashImageTarget = path.join(drawablePath, 'splash_image.png');
120
+ fs.copyFileSync(splashImageSource, splashImageTarget);
121
+ fs.writeFileSync(path.join(drawablePath, 'splash_background.xml'), splashDrawableContent, 'utf8');
122
+ console.log('Drawable splash resources updated.');
123
+ }
124
+
125
+ module.exports = updateStyles;