react-native-custom-splash 2.0.2 → 2.1.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 +1 -1
- package/plugin/src/index.js +123 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-custom-splash",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.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",
|
package/plugin/src/index.js
CHANGED
|
@@ -8,7 +8,6 @@ const {
|
|
|
8
8
|
} = require('@expo/config-plugins');
|
|
9
9
|
const path = require('path');
|
|
10
10
|
const fs = require('fs');
|
|
11
|
-
const { generateImageAsync } = require('@expo/image-utils');
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Validate and normalize plugin configuration
|
|
@@ -355,20 +354,107 @@ const withSplashScreenAndroid = (config, pluginConfig) => {
|
|
|
355
354
|
return config;
|
|
356
355
|
};
|
|
357
356
|
|
|
357
|
+
/**
|
|
358
|
+
* Create LaunchScreen.storyboard with splash configuration
|
|
359
|
+
*/
|
|
360
|
+
function createLaunchScreenStoryboard(hasImage, hasLogo, backgroundColor) {
|
|
361
|
+
const bgColor = backgroundColor.replace('#', '');
|
|
362
|
+
const r = parseInt(bgColor.substr(0, 2), 16) / 255;
|
|
363
|
+
const g = parseInt(bgColor.substr(2, 2), 16) / 255;
|
|
364
|
+
const b = parseInt(bgColor.substr(4, 2), 16) / 255;
|
|
365
|
+
|
|
366
|
+
const imageViewXML = hasImage ? `
|
|
367
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_image" translatesAutoresizingMaskIntoConstraints="NO" id="splashBgImage">
|
|
368
|
+
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
|
369
|
+
</imageView>` : '';
|
|
370
|
+
|
|
371
|
+
const logoViewXML = hasLogo ? `
|
|
372
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_logo" translatesAutoresizingMaskIntoConstraints="NO" id="splashLogo">
|
|
373
|
+
<rect key="frame" x="132" y="348" width="150" height="150"/>
|
|
374
|
+
<constraints>
|
|
375
|
+
<constraint firstAttribute="width" constant="150" id="logoWidth"/>
|
|
376
|
+
<constraint firstAttribute="height" constant="150" id="logoHeight"/>
|
|
377
|
+
</constraints>
|
|
378
|
+
</imageView>` : '';
|
|
379
|
+
|
|
380
|
+
const imageConstraints = hasImage ? `
|
|
381
|
+
<constraint firstItem="splashBgImage" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="bgTop"/>
|
|
382
|
+
<constraint firstItem="splashBgImage" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="bgLeading"/>
|
|
383
|
+
<constraint firstItem="splashBgImage" firstAttribute="trailing" secondItem="Ze5-6b-2t3" secondAttribute="trailing" id="bgTrailing"/>
|
|
384
|
+
<constraint firstItem="splashBgImage" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="bgBottom"/>` : '';
|
|
385
|
+
|
|
386
|
+
const logoConstraints = hasLogo ? `
|
|
387
|
+
<constraint firstItem="splashLogo" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="logoCenterX"/>
|
|
388
|
+
<constraint firstItem="splashLogo" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="logoCenterY"/>` : '';
|
|
389
|
+
|
|
390
|
+
const imageResources = [];
|
|
391
|
+
if (hasImage) imageResources.push('<image name="splash_image" width="1242" height="2688"/>');
|
|
392
|
+
if (hasLogo) imageResources.push('<image name="splash_logo" width="512" height="512"/>');
|
|
393
|
+
|
|
394
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
395
|
+
<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="01J-lp-oVM">
|
|
396
|
+
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
|
397
|
+
<dependencies>
|
|
398
|
+
<deployment identifier="iOS"/>
|
|
399
|
+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
|
|
400
|
+
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
401
|
+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
402
|
+
</dependencies>
|
|
403
|
+
<scenes>
|
|
404
|
+
<!--View Controller-->
|
|
405
|
+
<scene sceneID="EHf-IW-A2E">
|
|
406
|
+
<objects>
|
|
407
|
+
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
|
408
|
+
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
|
409
|
+
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
|
410
|
+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
411
|
+
<subviews>${imageViewXML}${logoViewXML}
|
|
412
|
+
</subviews>
|
|
413
|
+
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
|
414
|
+
<color key="backgroundColor" red="${r}" green="${g}" blue="${b}" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
415
|
+
<constraints>${imageConstraints}${logoConstraints}
|
|
416
|
+
</constraints>
|
|
417
|
+
</view>
|
|
418
|
+
</viewController>
|
|
419
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
420
|
+
</objects>
|
|
421
|
+
<point key="canvasLocation" x="53" y="375"/>
|
|
422
|
+
</scene>
|
|
423
|
+
</scenes>
|
|
424
|
+
<resources>${imageResources.join('\n ')}
|
|
425
|
+
</resources>
|
|
426
|
+
</document>`;
|
|
427
|
+
}
|
|
428
|
+
|
|
358
429
|
/**
|
|
359
430
|
* Plugin to configure iOS splash screen
|
|
360
431
|
*/
|
|
361
432
|
const withSplashScreenIOS = (config, pluginConfig) => {
|
|
362
|
-
|
|
433
|
+
// Step 1: Update Info.plist to use our LaunchScreen
|
|
434
|
+
config = IOSConfig.InfoPlist.withInfoPlist(config, (config) => {
|
|
435
|
+
// Set our LaunchScreen as the launch storyboard
|
|
436
|
+
config.modResults.UILaunchStoryboardName = 'LaunchScreen';
|
|
437
|
+
|
|
438
|
+
// Remove Expo's default splash screen configuration
|
|
439
|
+
delete config.modResults.UILaunchScreen;
|
|
440
|
+
|
|
441
|
+
return config;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// Step 2: Create our custom LaunchScreen.storyboard and copy images
|
|
445
|
+
config = withDangerousMod(config, [
|
|
363
446
|
'ios',
|
|
364
447
|
async (config) => {
|
|
365
448
|
const projectRoot = config.modRequest.projectRoot;
|
|
366
449
|
const iosProjectPath = config.modRequest.platformProjectRoot;
|
|
367
450
|
const projectName = config.modRequest.projectName;
|
|
368
451
|
|
|
452
|
+
let hasImage = false;
|
|
453
|
+
let hasLogo = false;
|
|
454
|
+
|
|
369
455
|
// Copy images to iOS assets
|
|
370
456
|
if (pluginConfig.image) {
|
|
371
|
-
await copyImageToIOS(
|
|
457
|
+
hasImage = await copyImageToIOS(
|
|
372
458
|
projectRoot,
|
|
373
459
|
pluginConfig.image,
|
|
374
460
|
'splash_image',
|
|
@@ -378,7 +464,7 @@ const withSplashScreenIOS = (config, pluginConfig) => {
|
|
|
378
464
|
}
|
|
379
465
|
|
|
380
466
|
if (pluginConfig.logo) {
|
|
381
|
-
await copyImageToIOS(
|
|
467
|
+
hasLogo = await copyImageToIOS(
|
|
382
468
|
projectRoot,
|
|
383
469
|
pluginConfig.logo,
|
|
384
470
|
'splash_logo',
|
|
@@ -387,9 +473,42 @@ const withSplashScreenIOS = (config, pluginConfig) => {
|
|
|
387
473
|
);
|
|
388
474
|
}
|
|
389
475
|
|
|
476
|
+
// Create LaunchScreen.storyboard
|
|
477
|
+
const launchScreenPath = path.join(
|
|
478
|
+
iosProjectPath,
|
|
479
|
+
projectName,
|
|
480
|
+
'LaunchScreen.storyboard'
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
const storyboardContent = createLaunchScreenStoryboard(
|
|
484
|
+
hasImage,
|
|
485
|
+
hasLogo,
|
|
486
|
+
pluginConfig.backgroundColor
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
fs.writeFileSync(launchScreenPath, storyboardContent);
|
|
490
|
+
|
|
491
|
+
// Remove SplashScreenLegacy if it exists (from Expo's default splash)
|
|
492
|
+
const legacyPath = path.join(
|
|
493
|
+
iosProjectPath,
|
|
494
|
+
projectName,
|
|
495
|
+
'Images.xcassets',
|
|
496
|
+
'SplashScreenLegacy.imageset'
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
if (fs.existsSync(legacyPath)) {
|
|
500
|
+
fs.rmSync(legacyPath, { recursive: true, force: true });
|
|
501
|
+
console.log('🗑️ Removed SplashScreenLegacy');
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
console.log('✅ iOS LaunchScreen.storyboard created with YOUR images!');
|
|
505
|
+
console.log('✅ Info.plist configured to use LaunchScreen');
|
|
506
|
+
|
|
390
507
|
return config;
|
|
391
508
|
},
|
|
392
509
|
]);
|
|
510
|
+
|
|
511
|
+
return config;
|
|
393
512
|
};
|
|
394
513
|
|
|
395
514
|
/**
|
|
@@ -407,8 +526,6 @@ module.exports = (config, props = {}) => {
|
|
|
407
526
|
pluginConfig = getPluginConfig(config);
|
|
408
527
|
}
|
|
409
528
|
|
|
410
|
-
console.log('✅ react-native-custom-splash configured with:', pluginConfig);
|
|
411
|
-
|
|
412
529
|
return withPlugins(config, [
|
|
413
530
|
[withSplashScreenAndroid, pluginConfig],
|
|
414
531
|
[withSplashScreenIOS, pluginConfig],
|