Skip to content

App is changing from Light to Dark Theme after Webpack HMR #289

Open

Description

@Tyler-V

Environment
image

Describe the bug
I am trying to ensure the app remains in light mode. When I am debugging I set my phone settings to enable dark mode. I then debug the app and initially it appears in light mode however when webpack reloads on a change during development, it then appears to apply the dark theme.

To Reproduce

  1. Turn dark mode on in the phone settings
  2. ns debug android on my connected Pixel 5 (Android 11)
  3. Change text in a component to trigger HMR
  4. App reloads and appears in the dark theme

image

Expected behavior
Dark mode should remain disabled and the ns-dark theme should not apply.

Additional context
I have tried the following to ensure dark mode does not apply, none prevent the app from changing from light to dark on HMR.

  1. Setting <item name="android:forceDarkAllowed">false</item> in styles.xml (values-v29)
  2. Annotating class="ns-light" on <page-router-outlet>
  3. Setting Theme.setMode(Theme.Light); manually on ngOnInit in the app component and main.ts
  4. Adding the following snipplet to force it to disable night mode in main.ts
if (android) {
    on(launchEvent, (args: ApplicationEventData) => {
        androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO);
    });
}

Activity

  1. changed the title [-]App is applying Dark Mode after Webpack HMR[/-] [+]App is changing from Light Mode to Dark Mode after Webpack HMR[/+] on Feb 17, 2021
  2. changed the title [-]App is changing from Light Mode to Dark Mode after Webpack HMR[/-] [+]App is changing from Light to Dark Theme after Webpack HMR[/+] on Feb 17, 2021
  3. csimpi commented on Feb 28, 2021

    @csimpi

    @Tyler-V Any news on this? We're having the same problem. I want to cut Dark Mode short and make sure the system setting won't override the app's theme.

  4. Tyler-V commented on Feb 28, 2021

    @Tyler-V
    Author

    @csimpi I have not found a solution for this, the only other option I can think of if it affects the actual production built app is to create a custom theme and override the dark theme that is applied by importing the nativescript prebuilt themes to use the same light theme.

  5. Tyler-V commented on Mar 1, 2021

    @Tyler-V
    Author

    After testing I can confirm this issue is isolated to Android and only during debugging after the first HMR, this issue thankfully does not exist in production on the built mobile app.

    As a temporary solution, you can modify your App_Resources/Android/src/main/res/values/colors.xml and change the ns_primaryDark color to whatever your ns_primary color is.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="ns_primary">#F5F5F5</color>
        <color name="ns_primaryDark">#F5F5F5</color>   <---
        <color name="ns_accent">#33B5E5</color>
        <color name="ns_blue">#272734</color>
    </resources>
    
  6. senner008 commented on Mar 5, 2021

    @senner008

    I have this happening seemingly at random with release builds also.
    As indicated I have not found a reliable way to reproduce yet.

    Phone : OnePlus 6T, Android 10

    Dependecies:

    
     "dependencies": {
        "@angular/animations": "~11.0.0",
        "@angular/common": "~11.0.0",
        "@angular/compiler": "~11.0.0",
        "@angular/core": "~11.0.0",
        "@angular/forms": "~11.0.0",
        "@angular/platform-browser": "~11.0.0",
        "@angular/platform-browser-dynamic": "~11.0.0",
        "@angular/router": "~11.0.0",
        "@nativescript-community/ble": "^3.0.13",
        "@nativescript/angular": "~11.0.0",
        "@nativescript/animated-circle": "^1.1.5",
        "@nativescript/core": "~7.0.0",
        "@nativescript/theme": "2.3.4",
        "@nstudio/nativescript-pulltorefresh": "^3.0.1",
        "@types/buffers": "^0.1.31",
        "@types/web-bluetooth": "0.0.8",
        "axios": "^0.21.1",
        "base-64": "^0.1.0",
        "buffer": "^5.6.0",
        "core-js": "^3.8.0",
        "crypto-js": "^3.3.0",
        "moment": "^2.27.0",
        "nativescript-appversion": "^1.4.4",
        "nativescript-background-fetch": "^1.2.1",
        "nativescript-couchbase-plugin": "^0.9.6",
        "nativescript-inappbrowser": "^3.0.1",
        "nativescript-permissions": "^1.3.11",
        "nativescript-screen-orientation": "^2.0.0",
        "reflect-metadata": "~0.1.12",
        "rxjs": "~6.6.0",
        "tslib": "~2.0.0",
        "uniqid": "^5.2.0",
        "uuid": "^8.2.0",
        "zone.js": "~0.11.1"
      },
      "devDependencies": {
        "@angular-devkit/build-angular": "~0.1100.0",
        "@angular/cli": "~11.0.0",
        "@angular/compiler-cli": "~11.0.0",
        "@nativescript/android": "7.0.1",
        "@nativescript/tslint-rules": "~0.0.5",
        "@nativescript/types": "~7.0.0",
        "@nativescript/webpack": "~3.0.0",
        "@types/jasmine": "~3.5.0",
        "@types/jasminewd2": "~2.0.3",
        "@types/node": "^12.11.1",
        "codelyzer": "^5.1.2",
        "husky": "^4.2.5",
        "jasmine-core": "~3.5.0",
        "jasmine-spec-reporter": "~4.2.1",
        "karma": "~4.4.1",
        "karma-chrome-launcher": "~3.1.0",
        "karma-coverage-istanbul-reporter": "~2.1.0",
        "karma-jasmine": "~3.0.1",
        "karma-jasmine-html-reporter": "^1.4.2",
        "node-sass": "^4.7.1",
        "prettier": "^2.2.1",
        "pretty-quick": "^3.1.0",
        "protractor": "~5.4.3",
        "ts-node": "~8.3.0",
        "tslint": "~6.1.0",
        "typescript": "~4.0.0"
      },
    
  7. NathanaelA commented on Mar 5, 2021

    @NathanaelA
  8. Tyler-V commented on Mar 5, 2021

    @Tyler-V
    Author

    @NathanaelA in the ticket additional context I've tried every possible option to disable dark mode completely which works when the application is built but resets as you've stated during HMR.

    I think the only way to disable dark theme if using the nativescript core themes is to create a custom theme / mixin where the dark theme color values are set to the light theme values although I have not tested this.

    This is strictly found in HMR on Android as you stated and does not impact production, just makes it a pain to continuously restart debugging if you are dealing with small text changes that may not show up against the dark theme based on your project.

  9. NathanaelA commented on Mar 5, 2021

    @NathanaelA
  10. senner007 commented on Mar 5, 2021

    @senner007

    It happens in production also.

    main.tns.ts :

    // @ts-ignore
    const myAndroidx: typeof androidx = androidx;
    // @ts-ignore
    const myAndroid: typeof android = android;
    // tslint:disable-next-line: typedef
    Application.android.on(launchEvent, (args: ApplicationEventData) => {
      myAndroidx.appcompat.app.AppCompatDelegate.setDefaultNightMode(
        myAndroidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO,
      );
    });
    
    export function forceLightTheme(): void {
      Theme.setMode(Theme.Light);
    }
    

    App_Resources\Android\values-v29\styles.xml :

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!-- Application theme -->
        <style name="AppThemeBase29" parent="AppThemeBase21">
            <item name="android:forceDarkAllowed">false</item>
        </style>
    
        <style name="AppTheme" parent="AppThemeBase29">
        </style>
    
    </resources>
    

    App_Resources\Android\values\colors.xml :

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="ns_primary">#F5F5F5</color>
    	<color name="ns_primaryDark">#F5F5F5</color>
    	<color name="ns_accent">#33B5E5</color>
        <color name="ns_blue">#272734</color>
    </resources>
    
    
  11. NathanaelA commented on Mar 5, 2021

    @NathanaelA
  12. senner007 commented on Mar 5, 2021

    @senner007

    No sure what you mean by too late.
    The lauchEvent code runs in main.tns.ts. Is that too late?

    I have this in my app.scss

    @import "~@nativescript/theme/core.compat";
    @import "~@nativescript/theme/blue.compat";
    

    if that what you are referring to?

    And yes Im calling the forceLightTheme() in app.module.tns.ts

    export class AppModule {
      constructor(private _state: StateService) {
        ...
        forceLightTheme();
        ... 
    

    the node_modules/@nativescript/theme/package.json says :
    "version": "2.3.4",

  13. NathanaelA commented on Mar 10, 2021

    @NathanaelA
  14. senner007 commented on Mar 10, 2021

    @senner007

    @NathanaelA - No and its difficult to get it to happen and unfortunately I don't have an Android 10 phone myself.

  15. NathanaelA commented on Mar 10, 2021

    @NathanaelA
  16. senner007 commented on Mar 10, 2021

    @senner007

    @NathanaelA - I repeatedly opened the app, then closed or supended it, did something else on the phone, then opened the app again and once in a while, although rarely, it would open with the dark mode theme.

  17. jalberto-ghub commented on Mar 26, 2021

    @jalberto-ghub

    I am experiencing a similar problem when I have the app running on the device and I change the display mode setting to dark-mode (tested on an Samsung Galaxy 9+). The colours will change to dark-mode but Theme.getMode() will report ns-light. It seems that the the two are out of sync. The only way I was able to fix it was by adding the following on main.tns.ts:

    // Android Launch Event
    if (global.isAndroid) {
        try {
            // Activity Started (app started/booted)
            Application.android.on(
              AndroidApplication.activityStartedEvent,
              (args: ApplicationEventData) => {
                androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode(
                  androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
                );
                setTimeout(() => {
                    Theme.setMode(Theme.Auto);
                    Theme.setMode(Theme.Light);
                }, 500);
                console.log('DarkMode Disabled on Android', Theme.getMode());
              }
            );
        } catch (e) {
          console.log('Error setting up Android Events', e);
        }
    }
    

    If you remove setting the mode to Theme.Auto it will not work. Also notice that from starting the app and as you change dark-modes on the settings page while the app is running you will see the following sequence of values for Theme.getMode():

    auto, ns-light, ns-light, ns-light, ns-light, ... no matter whether the app is rendering in dark-mode or not. Adding the Theme.setMode(Theme.Auto); seems to get things back in sync.

  18. ishiharas commented on Mar 22, 2022

    @ishiharas

    I'm running:
    "@nativescript/theme": "^3.0.2",
    "@nativescript/angular": "^12.2.0",
    "@nativescript/core": "^8.1.5",

    I've tried all the solutions, that can be found regarding this topic.

    @jalberto-ghub solution came close but wasn't consistent. Probably due the timeout. From time to time the dark mode would appear.

    I also tried force-dark-allowed with "ns clean" and rebuilding everything.

    I also tried setting the MODE_NIGHT_NO enum in onCreate/onStart in the android activity itself.

    The only solution through the various threads, that worked consistently for me, was the following.

    forceDarkMode() {
    	Theme.setMode(Theme.Auto);
    	Theme.setMode(Theme.Light);
    }
    

    and called the method in RadSidedrawer's - loaded method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions