Skip to content

Conversation

Copy link

Copilot AI commented Nov 25, 2025

User description

Implements a theme system supporting Light, Dark, and System (follows device) modes with Redux persistence.

Changes

  • Theme Context (src/Theme/)

    • colors.js: Light/dark color palettes (backgrounds, text, navigation, buttons, status colors)
    • ThemeContext.js: Provider component and useTheme() hook
    • Respects useColorScheme() when mode is "system"
  • Redux Integration

    • Added themeMode state ('light' | 'dark' | 'system') with persistence
    • Added setThemeMode action
  • UI Updates

    • Settings screen: Theme toggle (cycles System → Light → Dark) with contextual icons
    • BottomNavigation: Tab bar colors now theme-aware

Usage

import { useTheme } from '../../Theme';

function MyComponent() {
  const { colors, isDark, themeMode } = useTheme();
  
  return (
    <View style={{ backgroundColor: colors.background }}>
      <Text style={{ color: colors.text }}>Hello</Text>
    </View>
  );
}
Original prompt

This section details on the original issue you should resolve

<issue_title>feat: Add the Light & Dark theme</issue_title>
<issue_description>### Describe your suggested feature

Currently, the application doesn’t have a theme system, so we want to implement one. This way, we can use the light and dark themes in the app as needed.

Other details

No response

Acknowledgements

  • I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open or closed issue.
  • I have written a short but informative title.
  • I will fill out all of the requested information in this form.</issue_description>

<agent_instructions>I need to create the Light and Dark theme in the application make sure you do it correctly.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.


PR Type

Enhancement


Description

  • Implements complete light and dark theme system with Redux persistence

  • Adds ThemeProvider context for theme colors and mode management

  • Integrates theme support in Settings screen with mode toggle

  • Updates BottomNavigation and UI components to use theme colors

  • Supports system, light, and dark theme modes with automatic cycling


Diagram Walkthrough

flowchart LR
  Redux["Redux Store<br/>themeMode state"]
  ThemeProvider["ThemeProvider<br/>Context"]
  Colors["Color Palettes<br/>Light/Dark"]
  useTheme["useTheme Hook"]
  Components["UI Components<br/>Settings, Navigation"]
  
  Redux -->|themeMode| ThemeProvider
  Colors -->|colors| ThemeProvider
  ThemeProvider -->|provides context| useTheme
  useTheme -->|colors, isDark| Components
Loading

File Walkthrough

Relevant files
Enhancement
colors.js
Define light and dark color palettes                                         

src/Theme/colors.js

  • Defines comprehensive light and dark color palettes with 20+ semantic
    color tokens
  • Includes colors for backgrounds, text, navigation, buttons, status,
    and settings
  • Provides consistent color scheme across both themes
+126/-0 
ThemeContext.js
Create theme context and provider component                           

src/Theme/ThemeContext.js

  • Creates ThemeProvider component that wraps application with theme
    context
  • Implements useTheme hook for accessing current theme colors and mode
  • Determines theme based on Redux state and system color scheme
    preference
  • Uses useMemo for performance optimization
+76/-0   
index.js
Export theme module public API                                                     

src/Theme/index.js

  • Exports ThemeProvider, useTheme hook, and color palettes
  • Provides single entry point for theme module imports
+1/-0     
index.js
Add Redux theme mode state management                                       

src/Redux/Reducers/index.js

  • Adds themeMode state with default value 'system'
  • Implements setThemeMode action to update theme preference
  • Exports setThemeMode action for use in components
+6/-0     
index.js
Add theme toggle UI and apply theme colors                             

src/Screens/Settings/index.js

  • Adds theme toggle button that cycles through system, light, and dark
    modes
  • Implements getThemeModeLabel and getThemeModeIcon helper functions
  • Updates all hardcoded colors to use theme colors from useTheme hook
  • Adds analytics logging for theme mode changes
  • Displays current theme mode with contextual icon and label
+120/-7 
BottomNavigation.js
Apply theme colors to bottom navigation                                   

src/Navigation/BottomNavigation.js

  • Integrates useTheme hook to access theme colors
  • Replaces hardcoded tab bar colors with theme-aware colors
  • Updates tabBarBackground, tabBarActiveTintColor, and
    tabBarInactiveTintColor
+5/-3     
App.js
Integrate ThemeProvider into app root                                       

App.js

  • Imports ThemeProvider component
  • Wraps application tree with ThemeProvider to enable theme context
  • Positions ThemeProvider inside Redux Provider but outside
    PaperProvider
+10/-7   

Copilot AI and others added 2 commits November 25, 2025 11:03
Co-authored-by: pushpender-singh-ap <73298854+pushpender-singh-ap@users.noreply.github.com>
Co-authored-by: pushpender-singh-ap <73298854+pushpender-singh-ap@users.noreply.github.com>
Copilot AI changed the title [WIP] Add light and dark theme options to application feat: Add Light & Dark theme support Nov 25, 2025
@pushpender-singh-ap pushpender-singh-ap marked this pull request as ready for review November 25, 2025 11:12
@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
UI spoofing risk

Description: The theme toggle uses Alert.alert with a dynamic string built from state without
sanitization, which in rare cases could allow misleading UI if untrusted input reached
themeMode; verify inputs are constrained to expected literals.
index.js [97-104]

Referred Code
  dispatch(setThemeMode(newMode));

  Alert.alert(
    'Theme Changed',
    `App theme is now set to ${getThemeModeLabel(newMode)}.`,
    [{text: 'OK'}],
  );
};
Ticket Compliance
🟢
🎫 #60
🟢 Introduce an application-wide theme system.
Provide Light and Dark themes.
Allow using the system/device appearance to determine the app theme.
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Audit coverage: The PR adds a theme toggle action but only logs an analytics event without a clear audit
log including user identity and outcome, which may not meet comprehensive audit trail
requirements.

Referred Code
const handleThemeToggle = () => {
  analytics().logEvent('toggle_theme_mode', {
    item: 'Theme Mode',
    currentMode: themeMode,
  });

  let newMode;
  switch (themeMode) {
    case 'system':
      newMode = 'light';
      break;
    case 'light':
      newMode = 'dark';
      break;
    case 'dark':
    default:
      newMode = 'system';
      break;
  }

  dispatch(setThemeMode(newMode));


 ... (clipped 6 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Missing try/catch: The theme toggle dispatch and analytics call lack error handling, so failures (e.g.,
analytics rejection or Redux persistence errors) would not be caught or reported.

Referred Code
const handleThemeToggle = () => {
  analytics().logEvent('toggle_theme_mode', {
    item: 'Theme Mode',
    currentMode: themeMode,
  });

  let newMode;
  switch (themeMode) {
    case 'system':
      newMode = 'light';
      break;
    case 'light':
      newMode = 'dark';
      break;
    case 'dark':
    default:
      newMode = 'system';
      break;
  }

  dispatch(setThemeMode(newMode));


 ... (clipped 6 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Leverage react-native-paper's built-in theming

Instead of creating a custom theme context, the PR should utilize the built-in
theming system of react-native-paper. This involves defining themes compatible
with PaperProvider and using its useTheme hook for a unified solution.

Examples:

App.js [58-66]
            <ThemeProvider>
              <PaperProvider>
                <BannerProvider>
                  <RootNavigation />
                  <Toast />
                  <ForceUpdate />
                </BannerProvider>
              </PaperProvider>
            </ThemeProvider>
src/Theme/ThemeContext.js [1-74]
import React, {createContext, useContext, useMemo} from 'react';
import {useSelector} from 'react-redux';
import {useColorScheme} from 'react-native';
import {lightColors, darkColors} from './colors';

/**
 * @typedef {'light' | 'dark' | 'system'} ThemeMode
 */

/**

 ... (clipped 64 lines)

Solution Walkthrough:

Before:

// src/Theme/ThemeContext.js
const ThemeContext = createContext(...);
export function ThemeProvider({children}) {
  const themeMode = useSelector(...);
  const systemColorScheme = useColorScheme();
  const isDark = themeMode === 'system' ? systemColorScheme === 'dark' : themeMode === 'dark';
  const colors = isDark ? darkColors : lightColors;
  const value = { colors, isDark, themeMode };
  return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
export function useTheme() { return useContext(ThemeContext); }

// App.js
<Provider>
  <ThemeProvider>
    <PaperProvider>
      <RootNavigation />
    </PaperProvider>
  </ThemeProvider>
</Provider>

After:

// src/Theme/themes.js
import { MD3DarkTheme, MD3LightTheme } from 'react-native-paper';
// ... define custom colors
export const AppDarkTheme = { ...MD3DarkTheme, colors: { ...MD3DarkTheme.colors, ...customDarkColors } };
export const AppLightTheme = { ...MD3LightTheme, colors: { ...MD3LightTheme.colors, ...customLightColors } };

// App.js
import { PaperProvider } from 'react-native-paper';
import { AppDarkTheme, AppLightTheme } from './src/Theme/themes';

const AppContent = () => {
  const themeMode = useSelector(...);
  const systemColorScheme = useColorScheme();
  const isDark = themeMode === 'system' ? systemColorScheme === 'dark' : themeMode === 'dark';
  const theme = isDark ? AppDarkTheme : AppLightTheme;
  return <PaperProvider theme={theme}><RootNavigation /></PaperProvider>;
}
Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a major architectural flaw, as the PR reinvents a theming system that is already provided by the react-native-paper library, which is in use.

High
Possible issue
Correct inverted dark theme colors

Update the settingsItem and settingsItemText colors in darkColors to be
consistent with the dark theme, as they are currently inverted.

src/Theme/colors.js [120-122]

 // Settings specific
-settingsItem: '#FFFFFF',
-settingsItemText: '#000000',
+settingsItem: '#1C1C3A', // Using secondary background color
+settingsItemText: '#FFFFFF', // Using primary text color
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a visual bug where the dark theme colors for settings items are inverted, which would create a jarring user experience.

Medium
  • More

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive light and dark theme system for the InkNest application, adding support for three theme modes (light, dark, and system) with Redux persistence and React Context for theme management.

Key Changes:

  • Added theme infrastructure with color palettes, ThemeProvider context, and useTheme hook
  • Integrated theme mode state in Redux with persistence support
  • Updated Settings screen with theme toggle and partially applied theme colors throughout the UI

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Theme/colors.js Defines light and dark color palettes with semantic tokens for backgrounds, text, navigation, buttons, and status colors
src/Theme/ThemeContext.js Implements ThemeProvider component and useTheme hook for accessing theme colors and mode
src/Theme/index.js Exports theme module public API
src/Redux/Reducers/index.js Adds themeMode state management with setThemeMode action
src/Screens/Settings/index.js Adds theme toggle UI with cycling modes and applies theme colors to some settings items
src/Navigation/BottomNavigation.js Updates tab bar colors to use theme-aware colors
App.js Integrates ThemeProvider into the application component hierarchy

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

*/
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check if (!context) will never be true because the ThemeContext is created with a default value (lines 13-17). This error handling won't work as intended. Consider removing the default value from createContext() (pass undefined instead) to make this check effective, or remove the check entirely if a default fallback is desired.

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +122
settingsItem: '#FFFFFF',
settingsItemText: '#000000',
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dark theme colors for settingsItem (white) and settingsItemText (black) appear to be inverted. In dark mode, the background should be dark and text should be light, but here it's the opposite. This will result in white backgrounds with black text in dark mode, which contradicts the dark theme design. Consider changing settingsItem to a dark color (e.g., 'rgba(255, 255, 255, 0.05)') and settingsItemText to a light color (e.g., '#FFFFFF').

Suggested change
settingsItem: '#FFFFFF',
settingsItemText: '#000000',
settingsItem: 'rgba(255, 255, 255, 0.05)',
settingsItemText: '#FFFFFF',

Copilot uses AI. Check for mistakes.
alignItems: 'center',
justifyContent: 'space-between',
}}
onPress={handleThemeToggle}>
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The theme toggle TouchableOpacity is missing accessibility properties. Consider adding accessibilityRole="button", accessibilityLabel, and accessibilityHint to improve screen reader support. For example:

accessibilityRole="button"
accessibilityLabel={`Theme: ${getThemeModeLabel(themeMode)}`}
accessibilityHint="Double tap to cycle through System, Light, and Dark theme modes"
Suggested change
onPress={handleThemeToggle}>
onPress={handleThemeToggle}
accessibilityRole="button"
accessibilityLabel={`Theme: ${getThemeModeLabel(themeMode)}`}
accessibilityHint="Double tap to cycle through System, Light, and Dark theme modes"
>

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Add the Light & Dark theme

2 participants