diff --git a/android/build.gradle b/android/build.gradle index 43eb88f..ea98faa 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -130,9 +130,11 @@ repositories { } def kotlin_version = getExtOrDefault('kotlinVersion') +def webkit_version = getExtOrDefault('webkitVersion') dependencies { //noinspection GradleDynamicVersion implementation 'com.facebook.react:react-native:+' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "androidx.webkit:webkit:$webkit_version" } diff --git a/android/gradle.properties b/android/gradle.properties index 76ae422..6882a0a 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,5 @@ ReactNativeWebView_kotlinVersion=1.3.50 +ReactNativeWebView_webkitVersion=1.4.0 ReactNativeWebView_compileSdkVersion=29 ReactNativeWebView_buildToolsVersion=29.0.3 ReactNativeWebView_targetSdkVersion=28 diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java index b00af43..f743bbc 100644 --- a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java @@ -46,6 +46,8 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.core.content.ContextCompat; import androidx.core.util.Pair; +import androidx.webkit.WebSettingsCompat; +import androidx.webkit.WebViewFeature; import com.facebook.common.logging.FLog; import com.facebook.react.modules.core.PermissionAwareActivity; @@ -609,6 +611,27 @@ public class RNCWebViewManager extends SimpleViewManager { ((RNCWebView) view).setHasScrollEvent(hasScrollEvent); } + @ReactProp(name = "forceDarkOn") + public void setForceDarkOn(WebView view, boolean enabled) { + // Only Android 10+ support dark mode + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + // Switch WebView dark mode + if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { + int forceDarkMode = enabled ? WebSettingsCompat.FORCE_DARK_ON : WebSettingsCompat.FORCE_DARK_OFF; + WebSettingsCompat.setForceDark(view.getSettings(), forceDarkMode); + } + + // Set how WebView content should be darkened. + // PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: checks for the "color-scheme" tag. + // If present, it uses media queries. If absent, it applies user-agent (automatic) + // More information about Force Dark Strategy can be found here: + // https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setForceDarkStrategy(android.webkit.WebSettings) + if (enabled && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) { + WebSettingsCompat.setForceDarkStrategy(view.getSettings(), WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING); + } + } + } + @Override protected void addEventEmitters(ThemedReactContext reactContext, WebView view) { // Do not register default touch emitter and let WebView implementation handle touches diff --git a/docs/Reference.md b/docs/Reference.md index 358fad7..aebf216 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -80,6 +80,7 @@ This document lays out the current public properties and methods for the React N - [`autoManageStatusBarEnabled`](Reference.md#autoManageStatusBarEnabled) - [`setSupportMultipleWindows`](Reference.md#setSupportMultipleWindows) - [`enableApplePay`](Reference.md#enableApplePay) +- [`forceDarkOn`](Reference.md#forceDarkOn) ## Methods Index @@ -1420,6 +1421,23 @@ Example: ``` +### `forceDarkOn` + +Configuring Dark Theme +*NOTE* : The force dark setting is not persistent. You must call the static method every time your app process is started. + +*NOTE* : The change from day<->night mode is a configuration change so by default the activity will be restarted and pickup the new values to apply the theme. Take care when overriding this default behavior to ensure this method is still called when changes are made. + +| Type | Required | Platform | +| ------- | -------- | -------- | +| boolean | No | Android | + +Example: + +```javascript + +``` + ## Methods ### `goForward()`[⬆](#methods-index) diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index 70a91ad..87815a6 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -305,6 +305,7 @@ export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps { setDisplayZoomControls?: boolean, nestedScrollEnabled?: boolean; readonly urlPrefixesForDefaultIntent?: string[]; + forceDarkOn?: boolean; } export declare type ContentInsetAdjustmentBehavior = 'automatic' | 'scrollableAxes' | 'never' | 'always'; @@ -955,6 +956,19 @@ export interface AndroidWebViewProps extends WebViewSharedProps { */ allowsFullscreenVideo?: boolean; + /** + * Configuring Dark Theme + * + * *NOTE* : The force dark setting is not persistent. You must call the static method every time your app process is started. + * + * *NOTE* : The change from day<->night mode is a configuration change so by default the activity will be restarted + * and pickup the new values to apply the theme. + * Take care when overriding this default behavior to ensure this method is still called when changes are made. + * + * @platform android + */ + forceDarkOn?: boolean; + /** * Boolean value to control whether pinch zoom is enabled. Used only in Android. * Default to true