Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the Windows OS #514

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/windows-app-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Windows CI
on: [pull_request]

jobs:
run-windows-tests:
name: Build & run tests
runs-on: windows-2019

steps:
- uses: actions/checkout@v2
name: Checkout Code

- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: '12.18.3'

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1
with:
vs-version: 16.8

- name: Install example modules
run: |
cd examples
yarn --pure-lockfile
- name: Build release
run: |
cd examples
npx react-native run-windows --release --no-packager --no-launch --logging
- name: Start Appium server
shell: powershell
run: |
cd examples
Start-Process PowerShell -ArgumentList "yarn appium"
- name: Run tests
run: |
cd examples
yarn test:windows
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[ ![原理 解析](https://img.shields.io/badge/原理-解析-brightgreen.svg)](https://github.com/crazycodeboy/RNStudyNotes/blob/master/React%20Native%20%E9%97%AE%E9%A2%98%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E5%90%88%E9%9B%86/React%20Native%20%E5%90%AF%E5%8A%A8%E7%99%BD%E5%B1%8F%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E6%95%99%E7%A8%8B/React%20Native%20%E5%90%AF%E5%8A%A8%E7%99%BD%E5%B1%8F%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E6%95%99%E7%A8%8B.md)
[ ![Flutter](https://img.shields.io/badge/Flutter-brightgreen.svg)](https://github.com/crazycodeboy/flutter_splash_screen)

A splash screen API for react-native which can programatically hide and show the splash screen. Works on iOS and Android.
A splash screen API for react-native which can programatically hide and show the splash screen. Works on iOS, Android and Windows.

## Content

Expand Down Expand Up @@ -112,6 +112,20 @@ public class MainApplication extends Application implements ReactApplication {
`$(SRCROOT)/../node_modules/react-native-splash-screen/ios`


**Windows:**

##### Automatic install with autolinking on RNW
RNSplashScreen supports autolinking. Just call: `yarn add react-native-splash-screen`

##### Manual installation on RNW
1. `yarn add react-native-splash-screen`
2. Open your solution in Visual Studio 2019 (eg. `windows\yourapp.sln`)
3. Right-click Solution icon in Solution Explorer > Add > Existing Project...
4. Add `node_modules\[module name here]\windows\RNSplashScreen\RNSplashScreen.vcxproj`
5. Right-click main application project > Add > Reference...
6. Select `RNSplashScreen` in Solution Projects
7. In app `pch.h` add `#include "winrt/RNSplashScreen.h"`
8. In `App.cpp` add `PackageProviders().Append(winrt::RNSplashScreen::ReactPackageProvider());` before `InitializeComponent();`

### Third step(Plugin Configuration):

Expand Down Expand Up @@ -165,6 +179,43 @@ Update `AppDelegate.m` with the following additions:

```

**Windows:**

On Windows, `react-native-splash-screen` will use an element in the visual tree to show the splash screen, a XAML `RNSplashScreen::RNSplashScreenControl`.

To add this element, follow the following steps:

1. In the application's `pch.h` file, add `#include "winrt/RNSplashScreen.h"` if you haven't already.

2. In the application's main XAML file, add a `RNSplashScreen::RNSplashScreenControl` element right beneath the `react:ReactRootView` element.

As an example, in `windows/myapp/MainPage.xaml` from the `react-native-windows` app template this can be done by adding a XAML `Grid` with a `RNSplashScreen::RNSplashScreenControl` alongside the `ReactRootView`. Change `windows/myapp/MainPage.xaml` from:
```xaml
<Page
...
>
<react:ReactRootView
x:Name="ReactRootView"
...
/>
</Page>
```
to
```xaml
<Page
...
xmlns:rnsplashscreen="using:RNSplashScreen"
>
<Grid>
<react:ReactRootView
x:Name="ReactRootView"
...
/>
<rnsplashscreen:RNSplashScreenControl/>
</Grid>
</Page>
```

## Getting started

Import `react-native-splash-screen` in your JS file.
Expand Down Expand Up @@ -257,6 +308,14 @@ Customize your splash screen via `LaunchScreen.storyboard` or `LaunchScreen.xib`
- [via LaunchScreen.storyboard Tutorial](https://github.com/crazycodeboy/react-native-splash-screen/blob/master/add-LaunchScreen-tutorial-for-ios.md)


### Windows

`react-native-splash-screen` will use the splash screen image and background color defined in the application's `Package.appxmanifest` file.

Since UWP applications already have a splash screen, this makes it so that the splash screen is extended into the `react-native-windows` load process.

To configure the UWP splash screen, open `windows/myapp/Package.appxmanifest` in Visual Studio, open the `Visual Assets` tab and the `Splash Screen` horizontal tab. Add a Splash Screen image and define a background color.

## Usage

Use like so:
Expand Down
3 changes: 1 addition & 2 deletions examples/.flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
inexact-spread=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error
Expand All @@ -71,4 +70,4 @@ untyped-import
untyped-type-import

[version]
^0.113.0
^0.122.0
6 changes: 6 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,9 @@ buck-out/

# CocoaPods
/ios/Pods/

# MSBuild Binary and Structured Log
*.binlog

# Debug log
debug.log
66 changes: 43 additions & 23 deletions examples/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
Text,
TouchableOpacity,
Linking,
Button,
Platform,
} from 'react-native'
import SplashScreen from 'react-native-splash-screen'

Expand All @@ -26,30 +28,41 @@ export default class example extends Component {
SplashScreen.hide();
}


render() {
return (
<TouchableOpacity
style={styles.container}
onPress={(e)=> {
Linking.openURL('https://coding.imooc.com/class/304.html');
}}
>
<View >
<Text style={styles.item}>
SplashScreen 启动屏
</Text>
<Text style={styles.item}>
@:http://www.devio.org/
</Text>
<Text style={styles.item}>
GitHub:https://github.com/crazycodeboy
</Text>
<Text style={styles.item}>
Email:[email protected]
</Text>
</View>
</TouchableOpacity>
<View style={styles.container}>
<TouchableOpacity
onPress={(e)=> {
Linking.openURL('https://coding.imooc.com/class/304.html');
}}
>
<View >
<Text style={styles.item}>
SplashScreen 启动屏
</Text>
<Text style={styles.item}>
@:http://www.devio.org/
</Text>
<Text style={styles.item}>
GitHub:https://github.com/crazycodeboy
</Text>
<Text style={styles.item}>
Email:[email protected]
</Text>
</View>
</TouchableOpacity>
{
// Show splash screen again on Windows and Android, for 3s.
(Platform.OS === 'windows' || Platform.OS === 'android') &&
<View style={styles.showSplashButtonView}>
<Button
title={"Show splash screen again"}
testID={"ShowSplashScreenButton"}
onPress={()=> {SplashScreen.show(); setTimeout(()=> SplashScreen.hide(), 3000)}}
/>
</View>
}
</View>
)
}

Expand All @@ -59,7 +72,10 @@ const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f3f2f2',
marginTop: 30
paddingTop: 30,
paddingBottom: 30,
paddingLeft: 30,
paddingRight: 30,
},
item: {
fontSize: 20,
Expand All @@ -69,4 +85,8 @@ const styles = StyleSheet.create({
height: 0.3,
backgroundColor: 'darkgray',
},
showSplashButtonView: {
marginTop:30,
alignSelf: 'baseline',
}
})
57 changes: 57 additions & 0 deletions examples/__windows_tests__/Splash-screen-render-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { driver, By2 } from 'selenium-appium';
import { until } from 'selenium-webdriver';
import { PNG } from 'pngjs';
import pixelmatch from 'pixelmatch';

const setup = require('../jest-windows/driver.setup');
jest.setTimeout(60000);

function pngFromBase64(base64) {
const pngBuffer = Buffer.from(base64, 'base64');
return PNG.sync.read(pngBuffer);
};

const pixelThreshold = 30; // Allow 30 pixel difference, to account for minor differences.
function pixelDiffPNGs(img1, img2) {
return pixelmatch(img1.data, img2.data, null, img1.width, img1.height);
}

beforeAll(() => {
return driver.startWithCapabilities(setup.capabilites);
});

afterAll(() => {
return driver.quit();
});

describe('Control Renders', () => {

test('Renders Splash Screen', async () => {
await driver.wait(until.elementLocated(By2.nativeAccessibilityId('SplashImage')));

// Set window to specific size, so that screenshots are not too flaky.
await driver.manage().window().setRect({x:0, y:0, width:512, height:512});

await(driver.sleep(5000)); // Expect 5s to be enough for the app to load.
});

test('Shows Splash Screen again', async() => {
let screenshot_before_splash_screen = pngFromBase64(await driver.takeScreenshot());

By2.nativeAccessibilityId('ShowSplashScreenButton').click();

await(driver.sleep(1000)); // 1s should be enough for splash screen to appear.
let screenshot_during_splash_screen = pngFromBase64(await driver.takeScreenshot());

// Screen showing splash screen should be different than screen without splash screen.
expect(pixelDiffPNGs(screenshot_before_splash_screen, screenshot_during_splash_screen)).toBeGreaterThanOrEqual(pixelThreshold);

await(driver.sleep(5000)); // 5s should be enough for splash screen to disappear.
let screenshot_after_splash_screen = pngFromBase64(await driver.takeScreenshot());

// Screen after splash screen disappears should be equal to screen before splash screen appears.
expect(pixelDiffPNGs(screenshot_before_splash_screen, screenshot_after_splash_screen)).toBeLessThanOrEqual(pixelThreshold);

})

});
14 changes: 4 additions & 10 deletions examples/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import com.android.build.OutputFile
* // default. Can be overridden with ENTRY_FILE environment variable.
* entryFile: "index.android.js",
*
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
* // https://reactnative.dev/docs/performance#enable-the-ram-format
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
Expand Down Expand Up @@ -157,20 +157,13 @@ android {
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://facebook.github.io/react-native/docs/signed-apk-android.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}

packagingOptions {
pickFirst "lib/armeabi-v7a/libc++_shared.so"
pickFirst "lib/arm64-v8a/libc++_shared.so"
pickFirst "lib/x86/libc++_shared.so"
pickFirst "lib/x86_64/libc++_shared.so"
}

// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
Expand Down Expand Up @@ -200,6 +193,7 @@ dependencies {

debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}

debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
Expand All @@ -222,4 +216,4 @@ task copyDownloadableDepsToLibs(type: Copy) {
into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
8 changes: 4 additions & 4 deletions examples/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

buildscript {
ext {
buildToolsVersion = "28.0.3"
buildToolsVersion = "29.0.2"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
compileSdkVersion = 29
targetSdkVersion = 29
}
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.5.2")
classpath("com.android.tools.build:gradle:3.5.3")

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
2 changes: 1 addition & 1 deletion examples/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ android.useAndroidX=true
android.enableJetifier=true

# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.33.1
FLIPPER_VERSION=0.54.0
Loading