GoogleChromeLabs / bubblewrap

Bubblewrap is a Command Line Interface (CLI) that helps developers to create a Project for an Android application that launches an existing Progressive Web App (PWAs) using a Trusted Web Activity.
Apache License 2.0
2.4k stars 162 forks source link

Dynamic theme_color #429

Closed toniengelhardt closed 3 years ago

toniengelhardt commented 3 years ago

Is your feature request related to a problem? Please describe.

Many modern apps feature dark mode for better UX, meaning the app will have two (or even more) different color schemes depending on time of day or user setting. Currently however we are forced to choose a fixed status bar color and bottom drawer color in the manifest. This leads to a non-native look and severely compromises the design, especially on devices with rounded edges, e.g. Pixel 5.

Example:

Light Dark
Screenshot_20201220-105829 Screenshot_20201220-105845

Describe the solution you'd like

Since many of us that use TWAs to deploy their PWAs to the PlayStore are not familiar with Android dev and don't want to touch .gradle or Android config files the easiest solution would certainly be for the TWA to fetch the theme settings from the PWA and listen for changes, either from manifest, meta tags, body style or css class (ideally with separate settings for status bar at the top and drawer bar at the bottom).

The text color should also be customizable or automatically contrast to the background color, aka. white on dark theme colors and black on light ones.

Important is also that it should be possible to make these adjustments independent from the system theme color.

Expected result:

Seamless transition between light and dark

Light Dark
Screenshot_20201220-110317 Screenshot_20201220-113301
PEConn commented 3 years ago

The status bar at the top and the navigation bar at the bottom should reflect the theme-color of your web page. As far as I know, you can't combine this with media queries (to automatically have a certain theme colour for dark more and a different one for light, but you can set it from JavaScript.

However, having just tried this on my device, that doesn't seem to be the case, I'll look into it a bit further.

I'm not sure what you mean by "the text color should also be customizable"? Which text?

Are you specifically talking about the colours during the splash screen, or when using the app?

toniengelhardt commented 3 years ago

Thanks so much for looking at this @PEConn!

It does't need to be via media query, via JavaScript would be even better. However, changing the theme color dynamically with JavaScript doesn't seem to have any effect. It looks like the manifest is evaluated only once on startup.

With text color I meant the status bar text, aka. time, battery, etc. When changing the theme color from dark to light the text color would need to be changed from light to dark accordingly to have sufficient contrast to the background.

JohnRSim commented 3 years ago

I'm using it with svelte and the app header/ status bar is changing dynamically with the app and text colours change automatically based on contrast just by updating the meta tag.

20201229_161542.jpg

toniengelhardt commented 3 years ago

Thanks for weighing in @JohnRSim, that sounds amazing! I have a Nuxt app, so maybe the problem is actually on the web app side.

JohnRSim commented 3 years ago

@PEConn if I set themeColor as white in the twa-manifest.json when I launch the app the splash screen status bar is black with black text is this expected?

When the app launches the status bar shows white background with black text..

Thanks

JohnRSim commented 3 years ago

Also noticed if I set the theme color to blue in the manifest all works great and can change the theme color to green or red etc with JavaScript but if I try to set it to white it changes to whatever the theme color is set to ie blue.

Have tried with other colours and have the same issue.

JohnRSim commented 3 years ago

I was hoping I could set the statusbar themeColor to the same as the splash screen and then when the app launched revert with JS and change it to white as the base app UI colour.

toniengelhardt commented 3 years ago

@JohnRSim I managed to get the same result. Setting the initial theme-color to #FFFFFF and then dynamically changing it to dark works with some limitations:

1) only works when the device is not in dark mode, otherwise the status bar will always be weird dark aka. not really black 2) only works for the top status bar, the navigation bar on the bottom will stay black, it seems there is no way to change that without touching xml files 3) dynamically changing to white only works if the initial color is white, otherwise not (I think this is the reason I initially thought it does not work at all)

Nuxt code in case someone stumbles over it:

export default {
  computed: {
    activeTheme() {
      return ... // light or dark
    },
  },
  head() {
    return {
      meta: [
        {
          hid: 'theme-color',
          name: 'theme-color',
          content: this.activeTheme === 'dark' ? '#000000' : '#FFFFFF',
        }
      ],
    }
  },
}
JohnRSim commented 3 years ago

@toniengelhardt I agree I had all those issues my default was dark mode but have turned it off to do testing.

Number 2 I had but upgraded bubblewrap and options were in the manifest that let me change footer nav colours but no way to change it with JS which for me was fine I just needed to change the header

andreban commented 3 years ago

Hi everyone. Arriving late on the thread (just back from OOO).

Bubblewrap can tell the browser about the initial state only, as it hands-off control to the browser after the Trusted Web Activity is started. So I don't think there's much we can do in the project itself.

However, It does seem there are improvements to the browser that could support this use-case better? The best place for those is https://crbug.com/.

JohnRSim commented 3 years ago

Agreed - I'll followup with a ticket as I can replicate with PWA some issues.

On a similar topic is it possible that we can set a splash screen header colour as a separate manifest attribute so that it isn't the same as the browser theme?

Or transparent to use the splash screen BG?

Thanks

tomayac commented 3 years ago

Related issue: https://github.com/w3c/image-resource/issues/26 (@aarongustafson).

clshortfuse commented 3 years ago

Pretty sure this is from the Chrome for Android bug. It's not limited to just PWA. Chrome wont ever respect theme-color if Dark Mode is on:

https://bugs.chromium.org/p/chromium/issues/detail?id=980790

As for splash background-color, transparent works. It's valid, and Lightouse will no longer report is as invalid in the future: https://github.com/GoogleChrome/lighthouse/issues/9623

andreban commented 3 years ago

Closing this, as the issue is on the browser side and there's nothing that can be done in the Bubblewrap side.