Skip to content

Commit

Permalink
Create Styles.css before writing to it. Closes #141. Make all file ca…
Browse files Browse the repository at this point in the history
…lls synchronously to make code cleaner.
  • Loading branch information
jonbhanson committed Mar 16, 2021
1 parent 4d4d89c commit 0d97a5a
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 109 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,8 @@
## [1.1.1] - (2021-Mar-16)

* Create Styles.css before writing to it. Closes [#141](https://github.com/jonbhanson/flutter_native_splash/issues/141)
* Make all file calls synchronously to make code cleaner.

## [1.1.0] - (2021-Mar-15)

* Added option for background image. Closes [#22](https://github.com/jonbhanson/flutter_native_splash/issues/22).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -16,7 +16,7 @@ First, add `flutter_native_splash` as a dev dependency in your pubspec.yaml file

```yaml
dev_dependencies:
flutter_native_splash: ^1.1.0
flutter_native_splash: ^1.1.1
```

Don't forget to `flutter pub get`.
Expand Down
42 changes: 20 additions & 22 deletions lib/android.dart
Expand Up @@ -28,7 +28,7 @@ final List<_AndroidDrawableTemplate> _splashImagesDark =
];

/// Create Android splash screen
Future<void> _createAndroidSplash({
void _createAndroidSplash({
required String imagePath,
required String darkImagePath,
required String color,
Expand All @@ -37,21 +37,21 @@ Future<void> _createAndroidSplash({
required bool fullscreen,
required String backgroundImage,
required String darkBackgroundImage,
}) async {
}) {
if (imagePath.isNotEmpty) {
await _applyImageAndroid(imagePath: imagePath);
_applyImageAndroid(imagePath: imagePath);
}
if (darkImagePath.isNotEmpty) {
await _applyImageAndroid(imagePath: darkImagePath, dark: true);
_applyImageAndroid(imagePath: darkImagePath, dark: true);
}

await _applyLaunchBackgroundXml(
_applyLaunchBackgroundXml(
gravity: gravity,
launchBackgroundFilePath: _androidLaunchBackgroundFile,
showImage: imagePath.isNotEmpty,
);

await _createBackground(
_createBackground(
colorString: color,
darkColorString: darkColor,
darkBackgroundImageSource: darkBackgroundImage,
Expand All @@ -61,7 +61,7 @@ Future<void> _createAndroidSplash({
backgroundImageDestination: _androidDrawableFolder + 'background.png',
);

await _createBackground(
_createBackground(
colorString: color,
darkColorString: darkColor,
darkBackgroundImageSource: darkBackgroundImage,
Expand All @@ -72,34 +72,33 @@ Future<void> _createAndroidSplash({
);

if (darkColor.isNotEmpty) {
await _applyLaunchBackgroundXml(
_applyLaunchBackgroundXml(
gravity: gravity,
launchBackgroundFilePath: _androidLaunchDarkBackgroundFile,
showImage: imagePath.isNotEmpty,
);
}

if (await Directory(_androidV21DrawableFolder).exists()) {
await _applyLaunchBackgroundXml(
if (Directory(_androidV21DrawableFolder).existsSync()) {
_applyLaunchBackgroundXml(
gravity: gravity,
launchBackgroundFilePath: _androidV21LaunchBackgroundFile,
showImage: imagePath.isNotEmpty,
);
if (darkColor.isNotEmpty) {
await _applyLaunchBackgroundXml(
_applyLaunchBackgroundXml(
gravity: gravity,
launchBackgroundFilePath: _androidV21LaunchDarkBackgroundFile,
showImage: imagePath.isNotEmpty,
);
}
}

await _applyStylesXml(fullScreen: fullscreen);
_applyStylesXml(fullScreen: fullscreen);
}

/// Create splash screen as drawables for multiple screens (dpi)
Future<void> _applyImageAndroid(
{required String imagePath, bool dark = false}) async {
void _applyImageAndroid({required String imagePath, bool dark = false}) {
print('[Android] Creating ' + (dark ? 'dark mode ' : '') + 'splash images');

final file = File(imagePath);
Expand Down Expand Up @@ -138,14 +137,14 @@ void _saveImageAndroid(
}

/// Updates launch_background.xml adding splash image path
Future _applyLaunchBackgroundXml(
void _applyLaunchBackgroundXml(
{required String launchBackgroundFilePath,
required String gravity,
required bool showImage}) async {
required bool showImage}) {
print('[Android] Updating $launchBackgroundFilePath with splash image path');
final launchBackgroundFile = File(launchBackgroundFilePath);
var launchBackgroundDocument;
await launchBackgroundFile.create(recursive: true);
launchBackgroundFile.createSync(recursive: true);
launchBackgroundDocument = XmlDocument.parse(_androidLaunchBackgroundXml);

final layerList = launchBackgroundDocument.getElement('layer-list');
Expand All @@ -162,7 +161,7 @@ Future _applyLaunchBackgroundXml(
}

/// Create or update styles.xml full screen mode setting
Future<void> _applyStylesXml({required bool fullScreen}) async {
void _applyStylesXml({required bool fullScreen}) {
final stylesFile = File(_androidStylesFile);

if (!stylesFile.existsSync()) {
Expand All @@ -172,13 +171,12 @@ Future<void> _applyStylesXml({required bool fullScreen}) async {
_createStylesFileWithImagePath(stylesFile: stylesFile);
}
print('[Android] Updating styles.xml with full screen mode setting');
await _updateStylesFile(fullScreen: fullScreen, stylesFile: stylesFile);
_updateStylesFile(fullScreen: fullScreen, stylesFile: stylesFile);
}

/// Updates styles.xml adding full screen property
Future<void> _updateStylesFile(
{required bool fullScreen, required File stylesFile}) async {
final stylesDocument = XmlDocument.parse(await stylesFile.readAsString());
void _updateStylesFile({required bool fullScreen, required File stylesFile}) {
final stylesDocument = XmlDocument.parse(stylesFile.readAsStringSync());
final styles = stylesDocument.findAllElements('style');
if (styles.length == 1) {
print('[Android] Only 1 style in styles.xml. Flutter V2 embedding has 2 '
Expand Down
10 changes: 5 additions & 5 deletions lib/flutter_native_splash.dart
Expand Up @@ -13,16 +13,16 @@ import 'unsupported_platform.dart' // Stub implementation
if (dart.library.io) 'supported_platform.dart'; // dart:io implementation

/// Create splash screens for Android and iOS
Future<void> createSplash() async {
await tryCreateSplash();
void createSplash() {
tryCreateSplash();
}

/// Create splash screens for Android and iOS based on a config argument
Future<void> createSplashByConfig(Map<String, dynamic> config) async {
void createSplashByConfig(Map<String, dynamic> config) {
tryCreateSplashByConfig(config);
}

/// Remove any splash screen by setting the default white splash
Future<void> removeSplash() async {
await tryRemoveSplash();
void removeSplash() {
tryRemoveSplash();
}
95 changes: 45 additions & 50 deletions lib/ios.dart
Expand Up @@ -25,7 +25,7 @@ final List<_IosLaunchImageTemplate> _iOSSplashImagesDark =
];

/// Create iOS splash screen
Future<void> _createiOSSplash({
void _createiOSSplash({
required String imagePath,
required String darkImagePath,
required String color,
Expand All @@ -35,39 +35,35 @@ Future<void> _createiOSSplash({
required bool fullscreen,
required String backgroundImage,
required String darkBackgroundImage,
}) async {
}) {
if (imagePath.isNotEmpty) {
await _applyImageiOS(imagePath: imagePath);
_applyImageiOS(imagePath: imagePath);
} else {
final splashImage = Image(1, 1);
_iOSSplashImages.forEach((template) async {
await File(_iOSAssetsLaunchImageFolder + template.fileName)
.create(recursive: true)
.then((File file) {
file.writeAsBytesSync(encodePng(splashImage));
});
_iOSSplashImages.forEach((template) {
var file = File(_iOSAssetsLaunchImageFolder + template.fileName);
file.createSync(recursive: true);
file.writeAsBytesSync(encodePng(splashImage));
});
}

if (darkImagePath.isNotEmpty) {
await _applyImageiOS(imagePath: darkImagePath, dark: true);
_applyImageiOS(imagePath: darkImagePath, dark: true);
} else {
_iOSSplashImagesDark.forEach((template) {
final file = File(_iOSAssetsLaunchImageFolder + template.fileName);
if (file.existsSync()) file.deleteSync();
});
}

await File(_iOSAssetsLaunchImageFolder + 'Contents.json')
.create(recursive: true)
.then((File file) {
file.writeAsStringSync(
darkImagePath.isNotEmpty ? _iOSContentsJsonDark : _iOSContentsJson);
});
var launchImageFile = File(_iOSAssetsLaunchImageFolder + 'Contents.json');
launchImageFile.create(recursive: true);
launchImageFile.writeAsStringSync(
darkImagePath.isNotEmpty ? _iOSContentsJsonDark : _iOSContentsJson);

await _applyLaunchScreenStoryboard(
_applyLaunchScreenStoryboard(
imagePath: imagePath, iosContentMode: iosContentMode);
await _createBackground(
_createBackground(
colorString: color,
darkColorString: darkColor,
darkBackgroundImageSource: darkBackgroundImage,
Expand All @@ -78,20 +74,19 @@ Future<void> _createiOSSplash({
_iOSAssetsLaunchImageBackgroundFolder + 'background.png',
);

await File(_iOSAssetsLaunchImageBackgroundFolder + 'Contents.json')
.create(recursive: true)
.then((File file) {
file.writeAsStringSync(darkColor.isNotEmpty
? _iOSLaunchBackgroundDarkJson
: _iOSLaunchBackgroundJson);
});
var backgroundImageFile =
File(_iOSAssetsLaunchImageBackgroundFolder + 'Contents.json');
backgroundImageFile.createSync(recursive: true);

backgroundImageFile.writeAsStringSync(darkColor.isNotEmpty
? _iOSLaunchBackgroundDarkJson
: _iOSLaunchBackgroundJson);

await _applyInfoPList(plistFiles: plistFiles, fullscreen: fullscreen);
_applyInfoPList(plistFiles: plistFiles, fullscreen: fullscreen);
}

/// Create splash screen images for original size, @2x and @3x
Future<void> _applyImageiOS(
{required String imagePath, bool dark = false}) async {
void _applyImageiOS({required String imagePath, bool dark = false}) {
print('[iOS] Creating ' + (dark ? 'dark mode ' : '') + 'splash images');
if (!File(imagePath).existsSync()) {
throw _NoImageFileFoundException('The file $imagePath was not found.');
Expand Down Expand Up @@ -124,7 +119,7 @@ void _saveImageiOS(
}

/// Update LaunchScreen.storyboard adding width, height and color
Future _applyLaunchScreenStoryboard(
void _applyLaunchScreenStoryboard(
{required String imagePath, required String iosContentMode}) {
final file = File(_iOSLaunchScreenStoryboardFile);

Expand All @@ -142,8 +137,8 @@ Future _applyLaunchScreenStoryboard(
}

/// Updates LaunchScreen.storyboard adding splash image path
Future _updateLaunchScreenStoryboard(
{required String imagePath, required String iosContentMode}) async {
void _updateLaunchScreenStoryboard(
{required String imagePath, required String iosContentMode}) {
// Load the data
final file = File(_iOSLaunchScreenStoryboardFile);
final xmlDocument = XmlDocument.parse(file.readAsStringSync());
Expand Down Expand Up @@ -218,32 +213,33 @@ Future _updateLaunchScreenStoryboard(
}

/// Creates LaunchScreen.storyboard with splash image path
Future _createLaunchScreenStoryboard(
{required String imagePath, required String iosContentMode}) async {
var file = await File(_iOSLaunchScreenStoryboardFile).create(recursive: true);
await file.writeAsString(_iOSLaunchScreenStoryboardContent);
void _createLaunchScreenStoryboard(
{required String imagePath, required String iosContentMode}) {
var file = File(_iOSLaunchScreenStoryboardFile);
file.createSync(recursive: true);
file.writeAsStringSync(_iOSLaunchScreenStoryboardContent);
return _updateLaunchScreenStoryboard(
imagePath: imagePath, iosContentMode: iosContentMode);
}

Future<void> _createBackground({
void _createBackground({
required String colorString,
required String darkColorString,
required String backgroundImageSource,
required String darkBackgroundImageSource,
required String backgroundImageDestination,
required String darkBackgroundImageDestination,
}) async {
}) {
if (colorString.isNotEmpty) {
var background = Image(1, 1);
var redChannel = int.parse(colorString.substring(0, 2), radix: 16);
var greenChannel = int.parse(colorString.substring(2, 4), radix: 16);
var blueChannel = int.parse(colorString.substring(4, 6), radix: 16);
background.fill(
0xFF000000 + (blueChannel << 16) + (greenChannel << 8) + redChannel);
await File(backgroundImageDestination)
.create(recursive: true)
.then((File file) => file.writeAsBytesSync(encodePng(background)));
var file = File(backgroundImageDestination);
file.createSync(recursive: true);
file.writeAsBytesSync(encodePng(background));
} else if (backgroundImageSource.isNotEmpty) {
File(backgroundImageSource).copySync(backgroundImageDestination);
} else {
Expand All @@ -257,9 +253,9 @@ Future<void> _createBackground({
var blueChannel = int.parse(darkColorString.substring(4, 6), radix: 16);
background.fill(
0xFF000000 + (blueChannel << 16) + (greenChannel << 8) + redChannel);
await File(darkBackgroundImageDestination)
.create(recursive: true)
.then((File file) => file.writeAsBytesSync(encodePng(background)));
var file = File(darkBackgroundImageDestination);
file.create(recursive: true);
file.writeAsBytesSync(encodePng(background));
} else if (darkBackgroundImageSource.isNotEmpty) {
File(darkBackgroundImageSource).copySync(darkBackgroundImageDestination);
} else {
Expand All @@ -269,29 +265,28 @@ Future<void> _createBackground({
}

/// Update Info.plist for status bar behaviour (hidden/visible)
Future _applyInfoPList(
{List<String>? plistFiles, required bool fullscreen}) async {
void _applyInfoPList({List<String>? plistFiles, required bool fullscreen}) {
if (plistFiles == null) {
plistFiles = [];
plistFiles.add(_iOSInfoPlistFile);
}

plistFiles.forEach((plistFile) async {
if (!await File(plistFile).exists()) {
plistFiles.forEach((plistFile) {
if (!File(plistFile).existsSync()) {
throw _CantFindInfoPlistFile(
'File $plistFile not found. If you renamed the file, make sure to '
'specify it in the info_plist_files section of your '
'flutter_native_splash configuration.');
}

print('[iOS] Updating $plistFile for status bar hidden/visible');
await _updateInfoPlistFile(plistFile: plistFile, fullscreen: fullscreen);
_updateInfoPlistFile(plistFile: plistFile, fullscreen: fullscreen);
});
}

/// Update Infop.list with status bar hidden directive
Future _updateInfoPlistFile(
{required String plistFile, required bool fullscreen}) async {
void _updateInfoPlistFile(
{required String plistFile, required bool fullscreen}) {
// Load the data
final file = File(plistFile);
final xmlDocument = XmlDocument.parse(file.readAsStringSync());
Expand Down

0 comments on commit 0d97a5a

Please sign in to comment.