-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(webapis): introduce
@react-native-webapis/battery-status
- Loading branch information
Showing
24 changed files
with
456 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--- | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# @react-native-webapis/battery-status | ||
|
||
[![Build](https://github.com/microsoft/rnx-kit/actions/workflows/build.yml/badge.svg)](https://github.com/microsoft/rnx-kit/actions/workflows/build.yml) | ||
[![npm version](https://img.shields.io/npm/v/@react-native-webapis/battery-status)](https://www.npmjs.com/package/@react-native-webapis/battery-status) | ||
|
||
🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧 | ||
|
||
### THIS TOOL IS EXPERIMENTAL — USE WITH CAUTION | ||
|
||
🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧 | ||
|
||
[Battery Status API](https://developer.mozilla.org/en-US/docs/Web/API/Battery_Status_API) | ||
for React Native. | ||
|
||
## Motivation | ||
|
||
This is a prototype for the [React Native WebAPIs RFC](https://github.com/microsoft/rnx-kit/pull/2504) | ||
|
||
## Installation | ||
|
||
```sh | ||
yarn add @rnx-kit/polyfills --dev | ||
yarn add @react-native-webapis/battery-status | ||
``` | ||
|
||
or if you're using npm | ||
|
||
```sh | ||
npm add --save-dev @rnx-kit/polyfills | ||
npm add @react-native-webapis/battery-status | ||
``` | ||
|
||
## Usage | ||
|
||
```diff | ||
diff --git a/packages/test-app/metro.config.js b/packages/test-app/metro.config.js | ||
index 7c0dcfc2..df0f8b0d 100644 | ||
--- a/packages/test-app/metro.config.js | ||
+++ b/packages/test-app/metro.config.js | ||
@@ -33,4 +33,7 @@ module.exports = makeMetroConfig({ | ||
blacklistRE: blockList, | ||
blockList, | ||
}, | ||
+ serializer: { | ||
+ getModulesRunBeforeMainModule: require("@rnx-kit/polyfills").default, | ||
+ }, | ||
}); | ||
diff --git a/packages/test-app/src/App.native.tsx b/packages/test-app/src/App.native.tsx | ||
index 599634a9..b465f0fe 100644 | ||
--- a/packages/test-app/src/App.native.tsx | ||
+++ b/packages/test-app/src/App.native.tsx | ||
@@ -1,3 +1,5 @@ | ||
+// Temporary until we figure out how to magically inject WebAPIs | ||
+import "@react-native-webapis/battery-status"; | ||
import { acquireTokenWithScopes } from "@rnx-kit/react-native-auth"; | ||
// Both `internal` imports are used to verify that `metro-resolver-symlinks` | ||
// resolves them correctly when `experimental_retryResolvingFromDisk` is | ||
@@ -7,7 +9,7 @@ import { | ||
getRemoteDebuggingAvailability, | ||
} from "internal"; | ||
import { getHermesVersion } from "internal/hermes"; | ||
-import React, { useCallback, useMemo, useState } from "react"; | ||
+import React, { useCallback, useEffect, useMemo, useState } from "react"; | ||
import type { LayoutChangeEvent } from "react-native"; | ||
import { | ||
NativeModules, | ||
@@ -186,6 +188,14 @@ function App({ concurrentRoot }: { concurrentRoot?: boolean }) { | ||
[setFabric] | ||
); | ||
|
||
+ const [batteryLevel, setBatteryLevel] = useState(-1); | ||
+ useEffect(() => { | ||
+ // @ts-expect-error FIXME | ||
+ global.navigator.getBattery().then((status) => { | ||
+ setBatteryLevel(status.level); | ||
+ }); | ||
+ }, []); | ||
+ | ||
return ( | ||
<SafeAreaView style={styles.body}> | ||
<StatusBar barStyle={isDarkMode ? "light-content" : "dark-content"} /> | ||
@@ -195,6 +205,9 @@ function App({ concurrentRoot }: { concurrentRoot?: boolean }) { | ||
style={styles.body} | ||
> | ||
<Header /> | ||
+ <View style={styles.group}> | ||
+ <Feature value={batteryLevel.toFixed(2)}>Battery Level</Feature> | ||
+ </View> | ||
<View style={styles.group}> | ||
<Button onPress={startAcquireToken}>Acquire Token</Button> | ||
</View> | ||
``` |
30 changes: 30 additions & 0 deletions
30
incubator/@react-native-webapis/battery-status/RNWBatteryStatus.podspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
require 'json' | ||
|
||
package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) | ||
version = package['version'] | ||
repository = package['repository'] | ||
|
||
Pod::Spec.new do |s| | ||
s.name = 'RNWBatteryStatus' | ||
s.version = version | ||
s.author = { package['author']['name'] => package['author']['email'] } | ||
s.license = package['license'] | ||
s.homepage = package['homepage'] | ||
s.source = { :git => repository['url'], :tag => "#{package['name']}@#{version}" } | ||
s.summary = package['description'] | ||
|
||
s.ios.deployment_target = '13.0' | ||
s.osx.deployment_target = '10.15' | ||
|
||
s.dependency 'React-Core' | ||
|
||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } | ||
|
||
# Include both package and repository relative paths to allow the podspec to | ||
# be consumed from both a local path, and as a podspec outside a spec | ||
# repository. | ||
s.source_files = 'ios/*.{h,m}', # :path | ||
"#{repository['directory']}/ios/*.{h,m}" # :podspec | ||
s.public_header_files = 'ios/*.h', # :path | ||
"#{repository['directory']}/ios/*.h" # :podspec | ||
end |
73 changes: 73 additions & 0 deletions
73
incubator/@react-native-webapis/battery-status/android/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import java.nio.file.Paths | ||
|
||
buildscript { | ||
ext.findFile = { fileName -> | ||
def currentDirPath = rootDir == null ? null : rootDir.toString() | ||
|
||
while (currentDirPath != null) { | ||
def currentDir = file(currentDirPath); | ||
def requestedFile = Paths.get(currentDirPath, fileName).toFile() | ||
|
||
if (requestedFile.exists()) { | ||
return requestedFile | ||
} | ||
|
||
currentDirPath = currentDir.getParent() | ||
} | ||
|
||
return null | ||
} | ||
|
||
ext.findNodeModulesPath = { packageName -> | ||
return findFile(Paths.get("node_modules", packageName).toString()) | ||
} | ||
|
||
ext.getExtProp = { prop, defaultValue -> | ||
return rootProject.ext.has(prop) ? rootProject.ext.get(prop) : defaultValue | ||
} | ||
|
||
ext.kotlinVersion = getExtProp("kotlinVersion", "1.7.21") | ||
|
||
repositories { | ||
google() | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" | ||
} | ||
} | ||
|
||
plugins { | ||
id("com.android.library") | ||
id("org.jetbrains.kotlin.android") | ||
} | ||
|
||
repositories { | ||
maven { | ||
url("${findNodeModulesPath('react-native')}/android") | ||
} | ||
|
||
google() | ||
mavenCentral() | ||
} | ||
|
||
android { | ||
compileSdkVersion getExtProp("compileSdkVersion", 33) | ||
defaultConfig { | ||
minSdkVersion getExtProp("minSdkVersion", 23) | ||
targetSdkVersion getExtProp("targetSdkVersion", 29) | ||
} | ||
lintOptions { | ||
abortOnError false | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" | ||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" | ||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" | ||
|
||
//noinspection GradleDynamicVersion | ||
implementation "com.facebook.react:react-native:+" | ||
} |
3 changes: 3 additions & 0 deletions
3
incubator/@react-native-webapis/battery-status/android/gradle.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# These properties are required to enable AndroidX for the test app. | ||
android.useAndroidX=true | ||
android.enableJetifier=true |
4 changes: 4 additions & 0 deletions
4
incubator/@react-native-webapis/battery-status/android/src/main/AndroidManifest.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="org.reactnativewebapis.batterystatus"> | ||
</manifest> |
47 changes: 47 additions & 0 deletions
47
...-status/android/src/main/java/org/reactnativewebapis/batterystatus/BatteryStatusModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package org.reactnativewebapis.batterystatus | ||
|
||
import android.content.Context | ||
import android.os.BatteryManager | ||
import android.os.Build | ||
import com.facebook.react.bridge.Arguments | ||
import com.facebook.react.bridge.Promise | ||
import com.facebook.react.bridge.ReactApplicationContext | ||
import com.facebook.react.bridge.ReactContextBaseJavaModule | ||
import com.facebook.react.bridge.ReactMethod | ||
import com.facebook.react.bridge.ReactModuleWithSpec | ||
|
||
class BatteryStatusModule(context: ReactApplicationContext?) : | ||
ReactContextBaseJavaModule(context), ReactModuleWithSpec { | ||
|
||
companion object { | ||
const val NAME = "RNWBatteryStatus" | ||
} | ||
|
||
override fun getName(): String = NAME | ||
|
||
@ReactMethod | ||
fun getStatus(promise: Promise) { | ||
val batteryManager = | ||
reactApplicationContext.getSystemService(Context.BATTERY_SERVICE) as BatteryManager | ||
promise.resolve( | ||
Arguments.createMap().also { map -> | ||
map.putBoolean("charging", batteryManager.isCharging) | ||
map.putInt("chargingTime", batteryManager.getChargingTime()) | ||
map.putInt("dischargingTime", -1) | ||
map.putDouble("level", batteryManager.getBatteryLevel()) | ||
} | ||
) | ||
} | ||
} | ||
|
||
fun BatteryManager.getBatteryLevel(): Double { | ||
return getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) / 100.0 | ||
} | ||
|
||
fun BatteryManager.getChargingTime(): Int { | ||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||
(computeChargeTimeRemaining() / 1000).toInt() | ||
} else { | ||
-1 | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...status/android/src/main/java/org/reactnativewebapis/batterystatus/BatteryStatusPackage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.reactnativewebapis.batterystatus | ||
|
||
import com.facebook.react.TurboReactPackage | ||
import com.facebook.react.bridge.NativeModule | ||
import com.facebook.react.bridge.ReactApplicationContext | ||
import com.facebook.react.module.model.ReactModuleInfo | ||
import com.facebook.react.module.model.ReactModuleInfoProvider | ||
|
||
class BatteryStatusPackage : TurboReactPackage() { | ||
override fun getModule(name: String?, reactContext: ReactApplicationContext?): NativeModule { | ||
return when (name) { | ||
BatteryStatusModule.NAME -> BatteryStatusModule(reactContext) | ||
else -> throw IllegalArgumentException("No module named '$name'") | ||
} | ||
} | ||
|
||
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = | ||
ReactModuleInfoProvider { | ||
val info = ReactModuleInfo( | ||
BatteryStatusModule.NAME, | ||
BatteryStatusModule::class.java.name, | ||
false, | ||
false, | ||
false, | ||
false, | ||
false | ||
) | ||
mapOf(info.name() to info).toMutableMap() | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
incubator/@react-native-webapis/battery-status/ios/RNWBatteryStatus.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#import <Foundation/Foundation.h> | ||
|
||
#import <React/RCTBridgeModule.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface RNWBatteryStatus : NSObject <RCTBridgeModule> | ||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
34 changes: 34 additions & 0 deletions
34
incubator/@react-native-webapis/battery-status/ios/RNWBatteryStatus.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#import "RNWBatteryStatus.h" | ||
|
||
@implementation RNWBatteryStatus | ||
|
||
RCT_EXPORT_MODULE(RNWBatteryStatus) | ||
|
||
+ (BOOL)requiresMainQueueSetup | ||
{ | ||
return NO; | ||
} | ||
|
||
// clang-format off | ||
RCT_EXPORT_METHOD(getStatus:(RCTPromiseResolveBlock)resolve | ||
rejecter:(RCTPromiseRejectBlock)reject) | ||
// clang-format on | ||
{ | ||
UIDevice *device = [UIDevice currentDevice]; | ||
[device setBatteryMonitoringEnabled:YES]; | ||
|
||
UIDeviceBatteryState batteryState = [device batteryState]; | ||
BOOL isCharging = batteryState == UIDeviceBatteryStateCharging; | ||
NSDictionary *status = @{ | ||
@"charging": [NSNumber numberWithBool:isCharging], | ||
@"chargingTime": | ||
[NSNumber numberWithFloat:batteryState == UIDeviceBatteryStateFull ? 0 : -1], | ||
@"dischargingTime": [NSNumber numberWithFloat:-1], | ||
@"level": [NSNumber numberWithFloat:[device batteryLevel]], | ||
}; | ||
[device setBatteryMonitoringEnabled:NO]; | ||
|
||
resolve(status); | ||
} | ||
|
||
@end |
1 change: 1 addition & 0 deletions
1
...bator/@react-native-webapis/battery-status/ios/RNWBatteryStatus.xcodeproj/project.pbxproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/* Dummy file so @react-native-community/cli recognizes this as an iOS package */ |
Oops, something went wrong.