@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 +158 -0
- package/assets/splash_1.webp +0 -0
- package/bin/react-native-splash-helper +6 -0
- package/index.d.ts +27 -0
- package/index.js +11 -0
- package/package.json +40 -0
- package/scripts/cleanBin.js +24 -0
- package/scripts/generateSplash.js +51 -0
- package/scripts/updateStoryboard.js +97 -0
- package/scripts/updateStyles.js +125 -0
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+

|
|
2
|
+
[](https://www.npmjs.com/package/@sekizlipenguen/react-native-splash-helper)
|
|
3
|
+
[](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
|
+

|
|
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
|
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
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;
|