Repository: OneKeyHQ/app-monorepo
Pull request #7039: style: fix: align react-navigation and rootview background color with App (OK-37071)
Author: login: huhuanming
Created: 2025-04-03T17:49:45Z | Merged: 2025-04-07T06:42:00Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced dynamic background color customization that updates the app’s root view across platforms.
	- Enhanced theming integration so that the interface, including navigation, automatically adapts to light or dark modes.
	- Integrated advanced color handling to ensure precise and consistent color adjustments.
	- Added a new native module for setting the background color of the root view in both Android and iOS.
	- Implemented a new hook for managing background color updates based on theme changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java b/apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java
new file mode 100644
index 000000000000..c38e0483cc0c
--- /dev/null
+++ b/apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java
@@ -0,0 +1,49 @@
+package so.onekey.app.wallet;
+
+import android.app.Activity;
+import android.graphics.Color;
+
+import com.betomorrow.rnfilelogger.FileLoggerModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class RootViewBackgroundModule extends ReactContextBaseJavaModule {
+    private FileLoggerModule fileLogger;
+
+    public RootViewBackgroundModule(ReactApplicationContext context) {
+        super(context);
+        fileLogger = new FileLoggerModule(getReactApplicationContext());
+    }
+
+    @Override
+    public String getName() {
+        return "RootViewBackground";
+    }
+
+    public void log(String name, String msg) {
+        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+        String currentTime = sdf.format(new Date());
+        fileLogger.write(1, currentTime + " | INFO : app => native => RootViewBackground:" + name + ": " + msg);
+    }
+
+    @ReactMethod
+    public void setBackground(Double r, Double g, Double b, Double a) {
+        Activity activity = getCurrentActivity();
+        if (activity == null) {
+            return;
+        }
+        activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                android.view.View rootView = activity.getWindow().getDecorView();
+                int parsedColor = Color.argb(a.intValue(), r.intValue(), g.intValue(), b.intValue());
+                rootView.getRootView().setBackgroundColor(parsedColor);
+                log("setRootViewBackground", "rgba(" + r + ", " + g + ", " + b + ", " + a + ")");
+            }
+        });
+    }
+}
diff --git a/apps/mobile/android/app/src/prod/java/so/onekey/app/wallet/AutoUpdateModulePackage.java b/apps/mobile/android/app/src/prod/java/so/onekey/app/wallet/AutoUpdateModulePackage.java
index 32a160cc148c..0ed1b254f930 100644
--- a/apps/mobile/android/app/src/prod/java/so/onekey/app/wallet/AutoUpdateModulePackage.java
+++ b/apps/mobile/android/app/src/prod/java/so/onekey/app/wallet/AutoUpdateModulePackage.java
@@ -27,6 +27,7 @@ public List<NativeModule> createNativeModules(
             ReactApplicationContext reactContext) {
         List<NativeModule> modules = new ArrayList<>();
         modules.add(new AutoUpdateModule(reactContext));
+        modules.add(new RootViewBackgroundModule(reactContext));
         return modules;
     }
 }
diff --git a/apps/mobile/ios/RCTRootViewBackground.h b/apps/mobile/ios/RCTRootViewBackground.h
new file mode 100644
index 000000000000..0601afbc9711
--- /dev/null
+++ b/apps/mobile/ios/RCTRootViewBackground.h
@@ -0,0 +1,4 @@
+#import <React/RCTBridgeModule.h>
+@interface RCTRootViewBackground : NSObject <RCTBridgeModule>
+
+@end
diff --git a/apps/mobile/ios/RCTRootViewBackground.m b/apps/mobile/ios/RCTRootViewBackground.m
new file mode 100644
index 000000000000..e5e39239e0db
--- /dev/null
+++ b/apps/mobile/ios/RCTRootViewBackground.m
@@ -0,0 +1,25 @@
+#import "RCTRootViewBackground.h"
+#import <CocoaLumberjack/CocoaLumberjack.h>
+
+static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
+
+@implementation RCTRootViewBackground
+
+RCT_EXPORT_MODULE(RootViewBackground);
+
+- (dispatch_queue_t)methodQueue
+{
+  return dispatch_get_main_queue();
+}
+
+RCT_EXPORT_METHOD(setBackground:(double)r g:(double)g b:(double)b a:(double)a)
+{
+  dispatch_async( dispatch_get_main_queue(), ^{
+    UIColor *color = [[UIColor alloc] initWithRed:r/255 green:g/255 blue:b/255 alpha:a/255];
+    UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
+    rootViewController.view.backgroundColor = color;
+    DDLogDebug(@"setRootViewBackground: rgba(%f, %f, %f, %f)", r, g, b, a);
+  });
+}
+
+@end
diff --git a/package.json b/package.json
index d4152da315e6..8adc14f547b3 100644
--- a/package.json
+++ b/package.json
@@ -99,6 +99,7 @@
     "bignumber.js": "9.1.2",
     "bip174": "3.0.0-rc.1",
     "browserify-zlib": "^0.2.0",
+    "colord": "^2.9.3",
     "crypto-browserify": "^3.12.0",
     "custom-electron-titlebar": "4.2.8",
     "ejs-loader": "^0.5.0",
diff --git a/packages/components/src/layouts/Navigation/Navigator/NavigationContainer.tsx b/packages/components/src/layouts/Navigation/Navigator/NavigationContainer.tsx
index 4861145431b8..7a457797353a 100644
--- a/packages/components/src/layouts/Navigation/Navigator/NavigationContainer.tsx
+++ b/packages/components/src/layouts/Navigation/Navigator/NavigationContainer.tsx
@@ -5,12 +5,22 @@ import {
   useCallback,
   useContext,
   useEffect,
+  useMemo,
 } from 'react';
 
-import { NavigationContainer as RNNavigationContainer } from '@react-navigation/native';
+import {
+  DarkTheme,
+  DefaultTheme,
+  NavigationContainer as RNNavigationContainer,
+} from '@react-navigation/native';
+import { useTheme } from 'tamagui';
 
 import appGlobals from '@onekeyhq/shared/src/appGlobals';
+import { updateRootViewBackgroundColor } from '@onekeyhq/shared/src/modules3rdParty/rootview-background';
 import { navigationIntegration } from '@onekeyhq/shared/src/modules3rdParty/sentry';
+import platformEnv from '@onekeyhq/shared/src/platformEnv';
+
+import { useSettingConfig } from '../../../hocs/Provider/hooks/useProviderValue';
 
 import type { NavigationContainerRef } from '@react-navigation/native';
 import type { GetProps } from 'tamagui';
@@ -46,13 +56,39 @@ export const useOnRouterChange = (callback: IRouterChangeEvent) => {
   }, []);
 };
 
+const useUpdateRootViewBackgroundColor = (
+  color: string,
+  theme: 'light' | 'dark',
+) => {
+  useEffect(() => {
+    updateRootViewBackgroundColor(color, theme);
+  }, [color, theme]);
+};
+
 export function NavigationContainer(props: IBasicNavigationContainerProps) {
   const handleReady = useCallback(() => {
     navigationIntegration.registerNavigationContainer(rootNavigationRef);
   }, []);
+  const { theme: themeName } = useSettingConfig();
+  const theme = useTheme();
+
+  useUpdateRootViewBackgroundColor(theme.bgApp.val, themeName);
+
+  const themeOptions = useMemo(() => {
+    return {
+      dark: themeName === 'dark',
+      colors: {
+        ...(themeName === 'dark' ? DarkTheme : DefaultTheme).colors,
+        background: theme.bgApp.val,
+        card: theme.bgApp.val,
+        border: theme.bgApp.val,
+      },
+    };
+  }, [theme.bgApp.val, themeName]);
   return (
     <RNNavigationContainer
       {...props}
+      theme={themeOptions}
       ref={rootNavigationRef}
       onReady={handleReady}
     />
diff --git a/packages/kit/src/hooks/useThemeVariant.ts b/packages/kit/src/hooks/useThemeVariant.ts
index 662ebbc71e41..3e9c10115138 100644
--- a/packages/kit/src/hooks/useThemeVariant.ts
+++ b/packages/kit/src/hooks/useThemeVariant.ts
@@ -1,12 +1,8 @@
-import { useEffect } from 'react';
-
 import { useSettingsPersistAtom } from '@onekeyhq/kit-bg/src/states/jotai/atoms';
 import { defaultColorScheme } from '@onekeyhq/shared/src/config/appConfig';
-import platformEnv from '@onekeyhq/shared/src/platformEnv';
 
 import { useSystemColorScheme } from './useSystemColorScheme';
 
-export const THEME_PRELOAD_STORAGE_KEY = 'ONEKEY_THEME_PRELOAD';
 export function useThemeVariant() {
   const [{ theme }] = useSettingsPersistAtom();
   // startup theme on web: apps/ext/src/assets/preload-html-head.js
@@ -16,19 +12,3 @@ export function useThemeVariant() {
     theme === 'system' ? colorScheme ?? defaultColorScheme : theme;
   return themeVariant;
 }
-
-// sync theme variant to external storage
-export const useSyncThemeVariant = platformEnv.isNative
-  ? () => ({})
-  : () => {
-      const [{ theme }] = useSettingsPersistAtom();
-      useEffect(() => {
-        setTimeout(() => {
-          localStorage.setItem(THEME_PRELOAD_STORAGE_KEY, theme);
-          // startup theme on desktop: apps/desktop/app/app.ts 213L
-          if (platformEnv.isDesktop) {
-            globalThis.desktopApi?.changeTheme(theme);
-          }
-        });
-      }, [theme]);
-    };
diff --git a/packages/kit/src/provider/ThemeProvider.tsx b/packages/kit/src/provider/ThemeProvider.tsx
index c6ffcab0ceea..44de90ba5e96 100644
--- a/packages/kit/src/provider/ThemeProvider.tsx
+++ b/packages/kit/src/provider/ThemeProvider.tsx
@@ -7,13 +7,12 @@ import platformEnv from '@onekeyhq/shared/src/platformEnv';
 
 import backgroundApiProxy from '../background/instance/backgroundApiProxy';
 import { useLocaleVariant } from '../hooks/useLocaleVariant';
-import { useSyncThemeVariant, useThemeVariant } from '../hooks/useThemeVariant';
+import { useThemeVariant } from '../hooks/useThemeVariant';
 
 function BasicThemeProvider({ children }: PropsWithChildren<unknown>) {
   const themeVariant = useThemeVariant();
   const localeVariant = useLocaleVariant();
 
-  useSyncThemeVariant();
   const handleLocalChange = useCallback(() => {
     // refresh appLocale in kit-bg service
     if (platformEnv.isExtension) {
diff --git a/packages/shared/src/modules3rdParty/rootview-background/index.native.tsx b/packages/shared/src/modules3rdParty/rootview-background/index.native.tsx
new file mode 100644
index 000000000000..66af99061e8c
--- /dev/null
+++ b/packages/shared/src/modules3rdParty/rootview-background/index.native.tsx
@@ -0,0 +1,18 @@
+import { colord } from 'colord';
+import { NativeModules } from 'react-native';
+
+import type { IUpdateRootViewBackgroundColor } from './type';
+
+const { RootViewBackground } = NativeModules as {
+  RootViewBackground: {
+    setBackground: (r: number, g: number, b: number, a: number) => void;
+  };
+};
+
+export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
+  color: string,
+) => {
+  const parsedColor = colord(color);
+  const { r, g, b, a } = parsedColor.toRgb();
+  RootViewBackground.setBackground(r, g, b, Math.round(a * 255));
+};
diff --git a/packages/shared/src/modules3rdParty/rootview-background/index.tsx b/packages/shared/src/modules3rdParty/rootview-background/index.tsx
new file mode 100644
index 000000000000..ee690fac4ae7
--- /dev/null
+++ b/packages/shared/src/modules3rdParty/rootview-background/index.tsx
@@ -0,0 +1,18 @@
+import platformEnv from '@onekeyhq/shared/src/platformEnv';
+
+import type { IUpdateRootViewBackgroundColor } from './type';
+
+export const THEME_PRELOAD_STORAGE_KEY = 'ONEKEY_THEME_PRELOAD';
+
+export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
+  color: string,
+  theme: 'light' | 'dark',
+) => {
+  setTimeout(() => {
+    localStorage.setItem(THEME_PRELOAD_STORAGE_KEY, theme);
+    // startup theme on desktop: apps/desktop/app/app.ts 213L
+    if (platformEnv.isDesktop) {
+      globalThis.desktopApi?.changeTheme(theme);
+    }
+  });
+};
diff --git a/packages/shared/src/modules3rdParty/rootview-background/type.ts b/packages/shared/src/modules3rdParty/rootview-background/type.ts
new file mode 100644
index 000000000000..fc01f813156d
--- /dev/null
+++ b/packages/shared/src/modules3rdParty/rootview-background/type.ts
@@ -0,0 +1,4 @@
+export type IUpdateRootViewBackgroundColor = (
+  color: string,
+  theme: 'light' | 'dark',
+) => void;
diff --git a/yarn.lock b/yarn.lock
index e4d1bf18bd10..d412c1d390c8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6946,6 +6946,7 @@ __metadata:
     bip174: "npm:3.0.0-rc.1"
     browserify-zlib: "npm:^0.2.0"
     cheerio: "npm:^1.0.0-rc.12"
+    colord: "npm:^2.9.3"
     copy-webpack-plugin: "npm:^6.0.2"
     cross-env: "npm:^7.0.3"
     crypto-browserify: "npm:^3.12.0"
@@ -20145,7 +20146,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"colord@npm:^2.9.1":
+"colord@npm:^2.9.1, colord@npm:^2.9.3":
   version: 2.9.3
   resolution: "colord@npm:2.9.3"
   checksum: 10/907a4506d7307e2f580b471b581e992181ed75ab0c6925ece9ca46d88161d2fc50ed15891cd0556d0d9321237ca75afc9d462e4c050b939ef88428517f047f30


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 5**

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: ASSERTIVE**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 182a25f3b08a52759935e5417632679d9550d532 and 543c1858fc8bb6d4ae093d12453a22d41d339cd8.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `yarn.lock` is excluded by `!**/yarn.lock`, `!**/*.lock`

</details>

<details>
<summary>📒 Files selected for processing (11)</summary>

* `apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java` (1 hunks)
* `apps/mobile/android/app/src/prod/java/so/onekey/app/wallet/AutoUpdateModulePackage.java` (1 hunks)
* `apps/mobile/ios/RCTRootViewBackground.h` (1 hunks)
* `apps/mobile/ios/RCTRootViewBackground.m` (1 hunks)
* `package.json` (1 hunks)
* `packages/components/src/layouts/Navigation/Navigator/NavigationContainer.tsx` (2 hunks)
* `packages/kit/src/hooks/useThemeVariant.ts` (0 hunks)
* `packages/kit/src/provider/ThemeProvider.tsx` (1 hunks)
* `packages/shared/src/modules3rdParty/rootview-background/index.native.tsx` (1 hunks)
* `packages/shared/src/modules3rdParty/rootview-background/index.tsx` (1 hunks)
* `packages/shared/src/modules3rdParty/rootview-background/type.ts` (1 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* packages/kit/src/hooks/useThemeVariant.ts

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (3)</summary>

* GitHub Check: unittest (20.x)
* GitHub Check: Analyze (javascript-typescript)
* GitHub Check: lint (20.x)

</details>

<details>
<summary>🔇 Additional comments (18)</summary><blockquote>

<details>
<summary>package.json (1)</summary>

`102-102`: **Appropriate dependency addition for color manipulation.**

The colord library is correctly added to dependencies. This library processes color strings in the root view background update implementation.

</details>
<details>
<summary>packages/shared/src/modules3rdParty/rootview-background/type.ts (1)</summary>

`1-4`: **Well-defined type signature.**

Clean and clear type definition for the background color update function. The type signature properly includes theme parameter support.

</details>
<details>
<summary>apps/mobile/ios/RCTRootViewBackground.h (1)</summary>

`1-4`: **Appropriate native bridge module interface.**

The interface correctly inherits from NSObject and implements RCTBridgeModule protocol, following React Native's native module conventions.

</details>
<details>
<summary>packages/shared/src/modules3rdParty/rootview-background/index.native.tsx (1)</summary>

`6-10`: **Clean native module type definition.**

The RootViewBackground native module interface is properly typed with the setBackground method.

</details>
<details>
<summary>packages/kit/src/provider/ThemeProvider.tsx (1)</summary>

`10-10`: **Clean removal of unused import**

Good job removing the unused `useSyncThemeVariant` import. This simplifies the code and aligns with the background color update refactoring.

</details>
<details>
<summary>apps/mobile/android/app/src/prod/java/so/onekey/app/wallet/AutoUpdateModulePackage.java (1)</summary>

`30-30`: **Successfully registered the new native module**

Added RootViewBackgroundModule to the native modules list, making it accessible from JavaScript code. This enables background color control from React Native.

</details>
<details>
<summary>packages/shared/src/modules3rdParty/rootview-background/index.tsx (1)</summary>

`5-5`: **Clear constant naming**

Good constant name that clearly indicates its purpose for theme preloading.

</details>
<details>
<summary>packages/components/src/layouts/Navigation/Navigator/NavigationContainer.tsx (7)</summary>

`8-16`: **Clean import structure**

Good restructuring of imports. Adding `useMemo` and theme-related imports from React Navigation sets up the foundation for proper theme management.

---

`19-22`: **Good module integration**

Nice addition of the `updateRootViewBackgroundColor` import. This connects the UI logic to the native implementation.

---

`23-23`: **Proper hook import**

Good use of the settings hook to access theme configuration.

---

`59-66`: **Well-implemented custom hook**

The `useUpdateRootViewBackgroundColor` hook is clean and focused. It properly tracks dependencies with correct effect cleanup.

---

`72-75`: **Good theme configuration**

Nicely done retrieving theme settings and applying the background color update.

---

`77-87`: **Efficient theme options creation**

Good use of `useMemo` to create theme options. The dependency array is correct, and the theme structure follows React Navigation's requirements.

---

`91-91`: **Proper theme application**

The theme is correctly passed to the navigation container. This ensures consistent appearance.

</details>
<details>
<summary>apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java (4)</summary>

`1-13`: **Good module setup**

Clean package declaration and imports. All necessary components for React Native bridge and color handling are included.

---

`14-20`: **Proper module initialization**

Good class structure. The module extends the right base class and initializes the logger properly.

---

`22-25`: **Clear module naming**

Module name is descriptive and matches its functionality.

---

`33-48`: **Solid native implementation**

Good implementation of the background setting method:
- Proper activity null check
- Operations run on UI thread
- Correct color parsing from RGBA values
- Good use of logging

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T04:17:55Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: ASSERTIVE**
**Plan: Pro (Legacy)**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 543c1858fc8bb6d4ae093d12453a22d41d339cd8 and a6adfe05e00b16de3c219c9733a32dc7b1c0d8f2.

</details>

<details>
<summary>📒 Files selected for processing (2)</summary>

* `apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java` (1 hunks)
* `packages/shared/src/modules3rdParty/rootview-background/index.native.tsx` (1 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (3)</summary>

* GitHub Check: unittest (20.x)
* GitHub Check: lint (20.x)
* GitHub Check: Analyze (javascript-typescript)

</details>

<details>
<summary>🔇 Additional comments (2)</summary><blockquote>

<details>
<summary>packages/shared/src/modules3rdParty/rootview-background/index.native.tsx (1)</summary>

`1-18`: **Clear implementation for updating root view background color**

This function correctly handles parsing the color string and converts the alpha value to the expected format. 

The previous issues have been addressed:
1. Alpha is now properly extracted from the input color
2. The implementation matches the type definition

</details>
<details>
<summary>apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java (1)</summary>

`27-31`: **Log method looks good**

The log method properly formats and outputs the information with the correct module name.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T04:27:22Z
user: login: originalix
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-07T04:32:55Z
user: login: sidmorizon
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T04:32:57Z

Review comments:
diff_hunk: @@ -0,0 +1,22 @@
+import { colord } from 'colord';
+import { NativeModules } from 'react-native';
+
+import type { IUpdateRootViewBackgroundColor } from './type';
+
+const { RootViewBackground } = NativeModules as {
+  RootViewBackground: {
+    setBackground: (r: number, g: number, b: number, a: number) => void;
+  };
+};
+
+export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
+  color: string,
+) => {
+  const parsedColor = colord(color);
+  RootViewBackground.setBackground(
+    parsedColor.toRgb().r,
+    parsedColor.toRgb().g,
+    parsedColor.toRgb().b,
+    255,
+  );
path: packages/shared/src/modules3rdParty/rootview-background/index.native.tsx
user: login: coderabbitai[bot]
body: _🧹 Nitpick (assertive)_

**Consider making alpha configurable.**

The alpha value is hardcoded to 255 (fully opaque). Consider making this configurable for more flexibility.


```diff
export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
  color: string,
  theme: 'light' | 'dark',
) => {
  const parsedColor = colord(color);
+  const { r, g, b, a } = parsedColor.toRgb();
  RootViewBackground.setBackground(
-    parsedColor.toRgb().r,
-    parsedColor.toRgb().g,
-    parsedColor.toRgb().b,
-    255,
+    r,
+    g,
+    b,
+    Math.round(a * 255),
  );
};
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
  color: string,
  theme: 'light' | 'dark',
) => {
  const parsedColor = colord(color);
  const { r, g, b, a } = parsedColor.toRgb();
  RootViewBackground.setBackground(
    r,
    g,
    b,
    Math.round(a * 255),
  );
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-07T04:17:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,22 @@
+import { colord } from 'colord';
+import { NativeModules } from 'react-native';
+
+import type { IUpdateRootViewBackgroundColor } from './type';
+
+const { RootViewBackground } = NativeModules as {
+  RootViewBackground: {
+    setBackground: (r: number, g: number, b: number, a: number) => void;
+  };
+};
+
+export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
+  color: string,
+) => {
+  const parsedColor = colord(color);
+  RootViewBackground.setBackground(
+    parsedColor.toRgb().r,
+    parsedColor.toRgb().g,
+    parsedColor.toRgb().b,
+    255,
+  );
+};
path: packages/shared/src/modules3rdParty/rootview-background/index.native.tsx
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Implementation doesn't match type definition.**

The function implementation ignores the theme parameter that's defined in the type signature.


```diff
export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
  color: string,
+  theme: 'light' | 'dark',
) => {
  const parsedColor = colord(color);
  RootViewBackground.setBackground(
    parsedColor.toRgb().r,
    parsedColor.toRgb().g,
    parsedColor.toRgb().b,
    255,
  );
};
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
  color: string,
  theme: 'light' | 'dark',
) => {
  const parsedColor = colord(color);
  RootViewBackground.setBackground(
    parsedColor.toRgb().r,
    parsedColor.toRgb().g,
    parsedColor.toRgb().b,
    255,
  );
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-07T04:17:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,18 @@
+import platformEnv from '@onekeyhq/shared/src/platformEnv';
+
+import type { IUpdateRootViewBackgroundColor } from './type';
+
+export const THEME_PRELOAD_STORAGE_KEY = 'ONEKEY_THEME_PRELOAD';
+
+export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
+  color: string,
+  theme: 'light' | 'dark',
+) => {
+  setTimeout(() => {
+    localStorage.setItem(THEME_PRELOAD_STORAGE_KEY, theme);
+    // startup theme on desktop: apps/desktop/app/app.ts 213L
+    if (platformEnv.isDesktop) {
+      globalThis.desktopApi?.changeTheme(theme);
+    }
+  });
+};
path: packages/shared/src/modules3rdParty/rootview-background/index.tsx
user: login: coderabbitai[bot]
body: _🧹 Nitpick (assertive)_

**Consider explaining setTimeout usage**

The implementation works correctly, but why use setTimeout with no delay? Add a comment explaining this choice for better code clarity.


```diff
export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
  color: string,
  theme: 'light' | 'dark',
) => {
+  // Use setTimeout to make this operation non-blocking
  setTimeout(() => {
    localStorage.setItem(THEME_PRELOAD_STORAGE_KEY, theme);
    // startup theme on desktop: apps/desktop/app/app.ts 213L
    if (platformEnv.isDesktop) {
      globalThis.desktopApi?.changeTheme(theme);
    }
  });
};
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
export const updateRootViewBackgroundColor: IUpdateRootViewBackgroundColor = (
  color: string,
  theme: 'light' | 'dark',
) => {
  // Use setTimeout to make this operation non-blocking
  setTimeout(() => {
    localStorage.setItem(THEME_PRELOAD_STORAGE_KEY, theme);
    // startup theme on desktop: apps/desktop/app/app.ts 213L
    if (platformEnv.isDesktop) {
      globalThis.desktopApi?.changeTheme(theme);
    }
  });
};
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-07T04:17:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+#import "RCTRootViewBackground.h"
+#import <CocoaLumberjack/CocoaLumberjack.h>
+
+static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
+
+@implementation RCTRootViewBackground
+
+RCT_EXPORT_MODULE(RootViewBackground);
+
+- (dispatch_queue_t)methodQueue
+{
+  return dispatch_get_main_queue();
+}
+
+RCT_EXPORT_METHOD(setBackground:(double)r g:(double)g b:(double)b a:(double)a)
+{
+  dispatch_async( dispatch_get_main_queue(), ^{
+    UIColor *color = [[UIColor alloc] initWithRed:r/255 green:g/255 blue:b/255 alpha:a/255];
+    UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
+    rootViewController.view.backgroundColor = color;
+    DDLogDebug(@"setRootViewBackground: rgba(%f, %f, %f, %f)", r, g, b, a);
+  });
path: apps/mobile/ios/RCTRootViewBackground.m
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Fix alpha normalization and simplify queue handling**

Three issues to address:

1. Alpha values for UIColor should be 0-1, not 0-255.
2. The dispatch_async is redundant since methodQueue already returns the main queue.
3. Add a nil check for rootViewController.


```diff
- dispatch_async( dispatch_get_main_queue(), ^{
-   UIColor *color = [[UIColor alloc] initWithRed:r/255 green:g/255 blue:b/255 alpha:a/255];
-   UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
-   rootViewController.view.backgroundColor = color;
-   DDLogDebug(@"setRootViewBackground: rgba(%f, %f, %f, %f)", r, g, b, a);
- });
+ UIColor *color = [[UIColor alloc] initWithRed:r/255 green:g/255 blue:b/255 alpha:a];
+ UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
+ if (rootViewController) {
+   rootViewController.view.backgroundColor = color;
+   DDLogDebug(@"setRootViewBackground: rgba(%f, %f, %f, %f)", r, g, b, a);
+ } else {
+   DDLogError(@"Failed to set root view background: rootViewController is nil");
+ }
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  UIColor *color = [[UIColor alloc] initWithRed:r/255 green:g/255 blue:b/255 alpha:a];
  UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
  if (rootViewController) {
    rootViewController.view.backgroundColor = color;
    DDLogDebug(@"setRootViewBackground: rgba(%f, %f, %f, %f)", r, g, b, a);
  } else {
    DDLogError(@"Failed to set root view background: rootViewController is nil");
  }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-07T04:17:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,49 @@
+package so.onekey.app.wallet;
+
+import android.app.Activity;
+import android.graphics.Color;
+
+import com.betomorrow.rnfilelogger.FileLoggerModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class RootViewBackgroundModule extends ReactContextBaseJavaModule {
+    private FileLoggerModule fileLogger;
+
+    public RootViewBackgroundModule(ReactApplicationContext context) {
+        super(context);
+        fileLogger = new FileLoggerModule(getReactApplicationContext());
+    }
+
+    @Override
+    public String getName() {
+        return "RootViewBackground";
+    }
+
+    public void log(String name, String msg) {
+        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+        String currentTime = sdf.format(new Date());
+        fileLogger.write(1, currentTime + " | INFO : app => native => AutoUpdate:" + name + ": " + msg);
+    }
path: apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java
user: login: coderabbitai[bot]
body: _🧹 Nitpick (assertive)_

**Consider updating log message**

The log message contains "AutoUpdate" but this is a background module.

```diff
-        fileLogger.write(1, currentTime + " | INFO : app => native => AutoUpdate:" + name + ": " + msg);
+        fileLogger.write(1, currentTime + " | INFO : app => native => RootViewBackground:" + name + ": " + msg);
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
    public void log(String name, String msg) {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String currentTime = sdf.format(new Date());
        fileLogger.write(1, currentTime + " | INFO : app => native => RootViewBackground:" + name + ": " + msg);
    }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commits 6ba1812 to c905045
created_at: 2025-04-07T04:17:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,49 @@
+package so.onekey.app.wallet;
+
+import android.app.Activity;
+import android.graphics.Color;
+
+import com.betomorrow.rnfilelogger.FileLoggerModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class RootViewBackgroundModule extends ReactContextBaseJavaModule {
+    private FileLoggerModule fileLogger;
+
+    public RootViewBackgroundModule(ReactApplicationContext context) {
+        super(context);
+        fileLogger = new FileLoggerModule(getReactApplicationContext());
+    }
+
+    @Override
+    public String getName() {
+        return "RootViewBackground";
+    }
+
+    public void log(String name, String msg) {
+        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+        String currentTime = sdf.format(new Date());
+        fileLogger.write(1, currentTime + " | INFO : app => native => RootViewBackground:" + name + ": " + msg);
+    }
+
+    @ReactMethod
+    public void setBackground(Double r, Double g, Double b, Double a) {
+        Activity activity = getCurrentActivity();
+        if (activity == null) {
+            return;
+        }
+        activity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                android.view.View rootView = activity.getWindow().getDecorView();
+                int parsedColor = Color.argb(a.intValue(), r.intValue(), g.intValue(), b.intValue());
+                rootView.getRootView().setBackgroundColor(parsedColor);
+                log("setRootViewBackground", "rgba(" + r + ", " + g + ", " + b + ", " + a + ")");
+            }
+        });
+    }
path: apps/mobile/android/app/src/main/java/so/onekey/app/wallet/RootViewBackgroundModule.java
user: login: coderabbitai[bot]
body: _🧹 Nitpick (assertive)_

**Add error handling for more robust code**

The method silently returns if the activity is null but doesn't handle other potential errors.


```diff
public void setBackground(Double r, Double g, Double b, Double a) {
    Activity activity = getCurrentActivity();
    if (activity == null) {
+       log("setRootViewBackground", "Failed: Activity is null");
        return;
    }
    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
+           try {
                android.view.View rootView = activity.getWindow().getDecorView();
                int parsedColor = Color.argb(a.intValue(), r.intValue(), g.intValue(), b.intValue());
                rootView.getRootView().setBackgroundColor(parsedColor);
                log("setRootViewBackground", "rgba(" + r + ", " + g + ", " + b + ", " + a + ")");
+           } catch (Exception e) {
+               log("setRootViewBackground", "Error: " + e.getMessage());
+           }
        }
    });
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
    @ReactMethod
    public void setBackground(Double r, Double g, Double b, Double a) {
        Activity activity = getCurrentActivity();
        if (activity == null) {
            log("setRootViewBackground", "Failed: Activity is null");
            return;
        }
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    android.view.View rootView = activity.getWindow().getDecorView();
                    int parsedColor = Color.argb(a.intValue(), r.intValue(), g.intValue(), b.intValue());
                    rootView.getRootView().setBackgroundColor(parsedColor);
                    log("setRootViewBackground", "rgba(" + r + ", " + g + ", " + b + ", " + a + ")");
                } catch (Exception e) {
                    log("setRootViewBackground", "Error: " + e.getMessage());
                }
            }
        });
    }
`````

</details>

<!-- suggestion_end -->

---

_🧹 Nitpick (assertive)_

**Use primitive types instead of wrapper classes for better performance**

The method uses `Double` objects which causes unnecessary boxing/unboxing overhead.


```diff
- public void setBackground(Double r, Double g, Double b, Double a) {
+ public void setBackground(double r, double g, double b, double a) {
     Activity activity = getCurrentActivity();
     if (activity == null) {
         return;
     }
     activity.runOnUiThread(new Runnable() {
         @Override
         public void run() {
             android.view.View rootView = activity.getWindow().getDecorView();
-            int parsedColor = Color.argb(a.intValue(), r.intValue(), g.intValue(), b.intValue());
+            int parsedColor = Color.argb((int)a, (int)r, (int)g, (int)b);
             rootView.getRootView().setBackgroundColor(parsedColor);
             log("setRootViewBackground", "rgba(" + r + ", " + g + ", " + b + ", " + a + ")");
         }
     });
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
    @ReactMethod
    public void setBackground(double r, double g, double b, double a) {
        Activity activity = getCurrentActivity();
        if (activity == null) {
            return;
        }
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                android.view.View rootView = activity.getWindow().getDecorView();
                int parsedColor = Color.argb((int)a, (int)r, (int)g, (int)b);
                rootView.getRootView().setBackgroundColor(parsedColor);
                log("setRootViewBackground", "rgba(" + r + ", " + g + ", " + b + ", " + a + ")");
            }
        });
    }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-07T04:27:21Z
author_association: CONTRIBUTOR

PR comments:
user: login: codesandbox[bot]
created_at: 2025-04-03T17:49:48Z
body: #### Review or Edit in CodeSandbox

Open the branch in <a href="https://codesandbox.io/p/github/OneKeyHQ/app-monorepo/OK-37071?mode=review&utm_source=gh_app">Web Editor</a> &bull; <a href="https://codesandbox.io/p/vscode?owner=OneKeyHQ&repo=app-monorepo&branch=OK-37071&utm_source=gh_app">VS Code</a> &bull; <a href="https://codesandbox.io/p/vscode?owner=OneKeyHQ&repo=app-monorepo&branch=OK-37071&insiders=true&utm_source=gh_app">Insiders</a><br>
Open <a href="https://codesandbox.io/p/devtool/preview/OneKeyHQ/app-monorepo/OK-37071?task=preview&port=51423&redirect=true&utm_source=gh_app">Preview</a>

<!-- open-in-codesandbox:complete -->

author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-04-03T17:49:53Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
A new native module for updating the root view background color is introduced for both Android and iOS. The Android implementation uses a Java module, while the iOS side adds a corresponding interface and implementation. A new hook in the navigation component updates the background based on theme settings. A dependency for color manipulation was added, and legacy theme synchronization code was removed. Shared modules and types were also introduced to standardize the background update logic across platforms.

## Changes

| File(s) | Change Summary |
|---------|----------------|
| apps/mobile/android/app/.../RootViewBackgroundModule.java<br>apps/mobile/android/app/.../AutoUpdateModulePackage.java | Added a new Android native module to set the root view background and included it in the native modules list. |
| apps/mobile/ios/.../RCTRootViewBackground.h<br>apps/mobile/ios/.../RCTRootViewBackground.m | Introduced a new iOS native module to update the root view background with RGBA values and integrated logging. |
| package.json | Added dependency "colord" version "^2.9.3". |
| packages/components/src/layouts/.../NavigationContainer.tsx | Added a new hook to update the background color and enhanced theming logic in the NavigationContainer. |
| packages/kit/src/hooks/.../useThemeVariant.ts<br>packages/kit/src/provider/ThemeProvider.tsx | Removed theme synchronization logic and associated exports. |
| packages/shared/src/modules3rdParty/rootview-background/index.native.tsx<br>packages/shared/src/modules3rdParty/rootview-background/index.tsx<br>packages/shared/src/modules3rdParty/rootview-background/type.ts | Added shared modules and types to update the root view background via native modules and manage theme storage. |

## Sequence Diagram(s)
```mermaid
sequenceDiagram
    participant JS as JavaScript
    participant Hook as useUpdateRootViewBackgroundColor / updateRootViewBackgroundColor
    participant Native as RootViewBackgroundModule / RCTRootViewBackground
    participant UI as UI Thread

    JS->>Hook: Trigger background update with color string
    Hook->>Native: Parse color and call setBackground(r, g, b, a)
    Native->>UI: Update background color on main thread
    UI-->>Native: Confirm background update
    Native-->>JS: Log update action
```

## Assessment against linked issues

| Objective                                                                  | Addressed | Explanation |
|----------------------------------------------------------------------------|-----------|-------------|
| Fix white border on widescreen Android devices (OK-37071)                  | ✅        |             |

<!-- walkthrough_end -->
<!-- This is an auto-generated comment: all tool run failures by coderabbit.ai -->

> [!WARNING]
> There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.
> 
> <details>
> <summary>🔧 ESLint</summary>
> 
> > If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.
> 
> yarn install v1.22.22
> [1/4] Resolving packages...
> info There appears to be trouble with the npm registry (returned undefined). Retrying...
> info There appears to be trouble with the npm registry (returned undefined). Retrying...
> info There appears to be trouble with the npm registry (returned undefined). Retrying...
> info There appears to be trouble with the npm registry (returned undefined). Retrying...
> /opt/yarn-v1.22.22/lib/cli.js:66663
>             throw new (_errors || _load_errors()).ResponseError(_this3.reporter.lang('requestFailed', description), res.statusCode);
>             ^
> 
> ResponseError: Request failed "503 Service Unavailable"
>     at ResponseError.ExtendableBuiltin (/opt/yarn-v1.22.22/lib/cli.js:696:66)
>     at new ResponseError (/opt/yarn-v1.22.22/lib/cli.js:802:124)
>     at params.callback [as _callback] (/opt/yarn-v1.22.22/lib/cli.js:66663:19)
>     at self.callback (/opt/yarn-v1.22.22/lib/cli.js:141415:22)
>     at Request.emit (node:events:519:28)
>     at Request.<anonymous> (/opt/yarn-v1.22.22/lib/cli.js:142387:10)
>     at Request.emit (node:events:519:28)
>     at IncomingMessage.<anonymous> (/opt/yarn-v1.22.22/lib/cli.js:142309:12)
>     at Object.onceWrapper (node:events:633:28)
>     at IncomingMessage.emit (node:events:531:35) {
>   responseCode: 503
> }
> 
> Node.js v22.9.0
> 
> 
> 
> </details>

<!-- end of auto-generated comment: all tool run failures by coderabbit.ai -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=OneKeyHQ/app-monorepo&utm_content=7039):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai plan` to trigger planning for file edits and PR creation.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` or `Summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR